Skip to content

Latest commit

 

History

History
55 lines (44 loc) · 3.08 KB

reliability.md

File metadata and controls

55 lines (44 loc) · 3.08 KB

Reliability Through Week 10

Deadline Policy

Each worker starts one absolute steady-clock read deadline (default 5000 ms). Incoming bytes, interrupted system calls and readiness wakeups do not extend it. Header storage remains bounded to 8193 bytes: 8192 allowed plus one detection byte. After the handler returns, a separate absolute write deadline starts (5000 ms). Timeout throws a typed transport error; Executor increments timeout/error counts, logs one warning, and closes the socket through RAII. No 408 is attempted because the deadline is already exhausted. Normal truncated input still receives 400.

--read-timeout-ms and --write-timeout-ms accept 1..600000; zero is rejected, so deadlines cannot accidentally be disabled. poll waits at most 50 ms while individual reads/writes use MSG_DONTWAIT. write_all preserves partial progress and uses MSG_NOSIGNAL to prevent broken pipes from terminating the process.

These are service-phase deadlines, not total latency guarantees. Queued sockets wait for a worker; a bounded queue limits their count. Handlers are separately bounded to one million compute iterations or one second of simulated sleep. Admission-to-response deadlines could be a later extension.

Shutdown Policy

SIGINT/SIGTERM first disables admission and closes the queue to producers. --shutdown-grace-ms allows 0..60000 ms for admitted requests to finish; default zero preserves immediate cancellation. A single published monotonic deadline prevents duplicate shutdown calls from restarting the grace period. Main closes the listener when it leaves the accept loop. In single mode this happens after the current handler ends or cancellation interrupts it; the signal waiter independently enforces the grace deadline while main is occupied.

Outstanding work is counted before dispatch, so shutdown does not mistake queued or newly scheduled work for an idle server. At grace expiry, transport operations and sleep handlers observe cancellation; workers discard remaining queue entries and close their sockets. All workers are joined before shared state dies. active_connections, outstanding_connections, and queue_depth must all be zero in the final snapshot.

The grace is an allowance, not a promise to answer every request. It excludes OS scheduling delay and synchronous log sink delays. Use a regular log file or --log-level off if the output consumer can stall.

Failure Boundaries

Malformed syntax, unsupported methods/paths and invalid queries receive controlled HTTP errors. Unexpected application exceptions become 500, including body-free HEAD responses. Tests inject a throwing handler through Connection; no public fault endpoint was added. Send/reset failures close the connection and are logged. Oversized input can cause TCP reset after an error response because unread bytes remain; the test client preserves received HTTP bytes before a reset.

Allocation and thread-creation cleanup paths remain exception-safe, but allocator exhaustion and OS thread-creation failure are not deterministically injected in this milestone. See the failure checklist.