fix(metrics): correct frontend and backend protocol connection tracking across h1, h2, h3, and websocket traffic

This commit is contained in:
2026-04-04 18:54:05 +00:00
parent 3bfa451341
commit 1ad3e61c15
7 changed files with 125 additions and 58 deletions

View File

@@ -506,13 +506,14 @@ impl MetricsCollector {
total.fetch_add(1, Ordering::Relaxed);
}
/// Record a frontend request/connection closed with a given protocol.
/// Record a frontend connection closed with a given protocol.
pub fn frontend_protocol_closed(&self, proto: &str) {
let (active, _) = self.frontend_proto_counters(proto);
let val = active.load(Ordering::Relaxed);
if val > 0 {
active.fetch_sub(1, Ordering::Relaxed);
}
// Atomic saturating decrement — avoids TOCTOU race where concurrent
// closes could both read val=1, both subtract, wrapping to u64::MAX.
active.fetch_update(Ordering::Relaxed, Ordering::Relaxed, |v| {
if v > 0 { Some(v - 1) } else { None }
}).ok();
}
/// Record a backend connection opened with a given protocol.
@@ -525,10 +526,10 @@ impl MetricsCollector {
/// Record a backend connection closed with a given protocol.
pub fn backend_protocol_closed(&self, proto: &str) {
let (active, _) = self.backend_proto_counters(proto);
let val = active.load(Ordering::Relaxed);
if val > 0 {
active.fetch_sub(1, Ordering::Relaxed);
}
// Atomic saturating decrement — see frontend_protocol_closed for rationale.
active.fetch_update(Ordering::Relaxed, Ordering::Relaxed, |v| {
if v > 0 { Some(v - 1) } else { None }
}).ok();
}
// ── Per-backend recording methods ──