docs(websocket): record WS-13 no-keepalive decision + progress semantics (WS-13)
Decides the WS-13 legitimate-silence question as option (b): 60s of no chunk progress is an intentional eviction line even for silent subscriptions; no WS ping/pong keepalive is added because a keepalive can only rescue app-silence by re-arming the deadline, which reopens the dribble hole the knob exists to seal. Documented in the byte_adapter module doc, on DEFAULT_WS_IDLE_TIMEOUT, on the unchanged HttpAdapter::with_ws_idle_timeout knob, and in websocket.md (new 'Idle-read timeout' section, including the FWD-15 SSE-keepalive layering note). Deployment posture for long-lived silent sessions: with_ws_idle_timeout(None) + WsSessions abort + write-side caps.
This commit is contained in:
+14
-5
@@ -218,11 +218,20 @@ impl HttpAdapter {
|
||||
self
|
||||
}
|
||||
|
||||
/// The WS idle-read timeout (WS-01): the read pump closes the
|
||||
/// connection with a 1001 (GoingAway) close frame after this long
|
||||
/// without an inbound WS message — bounding the demux stall a
|
||||
/// dribbling (or silently-stalled) peer can pin. `None` disables
|
||||
/// the knob (not recommended: the stall window is then unbounded).
|
||||
/// The WS idle-read timeout (WS-01, WS-13 semantics): the read
|
||||
/// pump closes the connection with a 1001 (GoingAway) close frame
|
||||
/// after this long producing **no completed inbound chunk** — the
|
||||
/// deadline resets on demux progress (complete chunks forwarded
|
||||
/// into the byte stream), not on WS message arrival, so a
|
||||
/// dribbling peer (slow message arrivals inside a declared chunk)
|
||||
/// is bounded while productive-but-slow peers survive. This is an
|
||||
/// intentional no-progress eviction line, not a transport-idle
|
||||
/// bound: there is no WS ping/pong keepalive, and app-silence that
|
||||
/// outlasts the window (a quiet subscription) is evicted by design
|
||||
/// — see `websocket::byte_adapter`'s module doc. `None` disables
|
||||
/// the knob (not recommended: the stall window is then unbounded;
|
||||
/// long-lived silent subscriptions are the intended `None` case,
|
||||
/// leaning on `WsSessions::abort` and the write-side caps).
|
||||
///
|
||||
/// Default: [`crate::websocket::DEFAULT_WS_IDLE_TIMEOUT`] (60 s).
|
||||
pub fn with_ws_idle_timeout(mut self, idle_timeout: Option<Duration>) -> Self {
|
||||
|
||||
Reference in New Issue
Block a user