Skip to main content

Module http_connection_limiter

Module http_connection_limiter 

Source
Expand description

Bounded handler-thread admission for the clear-text HTTP accept loop.

Slice 1 of issue #570 / parent #569. The synchronous HTTP transport spawns one OS thread per accepted connection. Without an admission cap the server can degrade into thread-storm and lock starvation under load. HttpConnectionLimiter is a single AtomicUsize-backed semaphore consulted in the accept loop before parsing or handler work. A rejected connection gets a static 503 + Retry-After written and the socket closed without ever entering the runtime.

Hard cap for this slice is (2 * available_parallelism).clamp(8, 256). Config knobs (env / CLI) land in slice 5 per the parent brief.

Beyond admission, the limiter keeps a single rejection counter and an injectable monotonic clock (issue #620). Every try_acquire that hits the cap bumps the counter; observe() snapshots-and-resets it against the elapsed wall to derive a rejection rate. v1 ships a constant Retry-After; the rate signal is what a future v2 will use to make Retry-After adaptive. The clock is a trait so tests drive the rate deterministically without sleeping.

Structs§

HandlerDeadline
Per-handler total wall-clock deadline (issue #621), armed against the same MonotonicClock abstraction the limiter uses. The clear-text (and TLS) HTTP handler arms one of these at spawn and polls expired at coarse boundaries (between parse, route dispatch, and write). Production wires SystemMonotonicClock, so the deadline tracks real wall time; tests inject a fake clock to drive expiry deterministically without sleep().
HttpConnectionLimiter
HttpConnectionPermit
Permit handle — owns one slot of the limiter. Dropping the permit returns the slot. The permit is intentionally !Clone so the slot accounting can’t drift.
LimiterObservation
Snapshot returned by HttpConnectionLimiter::observe: the rejections accumulated since the previous observe, the wall elapsed across that window, and the derived rate. rejections_per_sec is 0.0 for a zero-length window (no time has passed) so callers never divide by zero.
SystemMonotonicClock
Real monotonic clock: nanoseconds since the limiter’s construction.

Traits§

MonotonicClock
Monotonic clock abstraction. Production uses SystemMonotonicClock (a process-start Instant baseline); tests inject a fake that can be advanced by hand so the rejection-rate derivation is deterministic.