v0.35.1: performance, AGPL licensing and documentation overhaul

- Web Server reads static files inline; proxy middleware chain flattened
- About window with license summary and project links; AGPL-3.0-or-later
- Rewritten documentation: feature list, screenshots, performance guide
- Fix false spikes in per-Vhost request-rate charts
This commit is contained in:
gru committed 2026-11-05 18:29:56 +01:00
1 parent d3b492874b
commit eba9f89283
135 files changed
+1425 -1064

No files matched your search

+44 -1
View File
@@ -1,3 +1,6 @@
const UNCACHEABLE_MEMO_TTL: Duration = Duration::from_secs(30);
const UNCACHEABLE_MEMO_CAPACITY: usize = 8192;
struct FillFlight {
id: u64,
scope: String,
@@ -50,7 +53,7 @@ impl Drop for FillLeaderGuard {
impl Cache {
pub async fn claim_fill(self: &Arc<Self>, ticket: &Ticket, settings: &Settings) -> FillClaim {
if !settings.collapse_enabled {
if !settings.collapse_enabled || self.recently_uncacheable(&ticket.key) {
return FillClaim::Disabled;
}
let existing = {
@@ -116,7 +119,46 @@ impl Cache {
}
}
/// Marks a key as uncacheable so requests skip coalescing.
pub fn remember_uncacheable(&self, ticket: &Ticket) {
let now = std::time::Instant::now();
let mut memo = self
.uncacheable_until
.lock()
.unwrap_or_else(|e| e.into_inner());
if memo.len() >= UNCACHEABLE_MEMO_CAPACITY {
memo.retain(|_, until| *until > now);
if memo.len() >= UNCACHEABLE_MEMO_CAPACITY {
return;
}
}
memo.insert(ticket.key, now + UNCACHEABLE_MEMO_TTL);
}
fn recently_uncacheable(&self, key: &Key) -> bool {
let mut memo = self
.uncacheable_until
.lock()
.unwrap_or_else(|e| e.into_inner());
match memo.get(key) {
Some(until) if *until > std::time::Instant::now() => true,
Some(_) => {
memo.remove(key);
false
}
None => false,
}
}
fn forget_uncacheable(&self) {
self.uncacheable_until
.lock()
.unwrap_or_else(|e| e.into_inner())
.clear();
}
fn cancel_all_fill_flights(&self) {
self.forget_uncacheable();
let flights = {
let mut flights = self.fill_flights.lock().unwrap_or_else(|e| e.into_inner());
flights
@@ -130,6 +172,7 @@ impl Cache {
}
fn cancel_scope_fill_flights(&self, scope: &str) {
self.forget_uncacheable();
let removed = {
let mut flights = self.fill_flights.lock().unwrap_or_else(|e| e.into_inner());
let keys = flights