Skip to content

Router: add a configurable SSE server write timeout #3175

Description

@mwisner

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions