Component
Router
Problem
A downstream client can stop reading an SSE subscription while leaving the connection open. The router's response write or flush can then block indefinitely.
For subscriptions backed by a shared trigger, that stalled write can prevent later events from reaching otherwise healthy subscribers. The router already bounds WebSocket writes with engine.websocket_server_write_timeout, but SSE delivery has no equivalent safeguard.
Proposed behavior
Add a separately configurable timeout for downstream SSE writes:
- expose
engine.sse_server_write_timeout and ENGINE_SSE_SERVER_WRITE_TIMEOUT
- keep the timeout disabled by default for backward compatibility
- apply a fresh deadline to the initial SSE response, data events, heartbeats, and completion events
- when configured, fail the affected SSE connection if the deadline cannot be applied or a write/flush exceeds it
- isolate and remove the stalled subscriber so healthy subscribers can continue receiving shared-trigger events
- preserve existing multipart behavior and SSE behavior when the timeout is disabled
This should conceptually mirror the existing WebSocket server write timeout while remaining independently configurable for SSE transports.
Acceptance criteria
- Negative timeout values are rejected during configuration loading.
- Zero preserves the existing no-deadline behavior.
- A positive timeout bounds each downstream SSE write/flush.
- Header, data, heartbeat, and completion paths are covered by tests.
- A blocked SSE subscriber times out without preventing a healthy subscriber from receiving a subsequent event from the same shared trigger.
- Existing multipart and disabled-timeout behavior remains covered.
Implementation
Proposed implementation: #3172
Component
Router
Problem
A downstream client can stop reading an SSE subscription while leaving the connection open. The router's response write or flush can then block indefinitely.
For subscriptions backed by a shared trigger, that stalled write can prevent later events from reaching otherwise healthy subscribers. The router already bounds WebSocket writes with
engine.websocket_server_write_timeout, but SSE delivery has no equivalent safeguard.Proposed behavior
Add a separately configurable timeout for downstream SSE writes:
engine.sse_server_write_timeoutandENGINE_SSE_SERVER_WRITE_TIMEOUTThis should conceptually mirror the existing WebSocket server write timeout while remaining independently configurable for SSE transports.
Acceptance criteria
Implementation
Proposed implementation: #3172