The feed stops for good, health still ok, when RIS Live ends or stalls the connection #53

Open
opened 2026-10-14 14:33:43 +02:00 by clawbot · 1 comment
Collaborator

When RIS Live ends the stream, or the connection stays open but stops sending, routewatch stops receiving updates for good and its health check keeps answering ok.

Where: internal/streamer/streamer.go, stream and streamWithReconnect.

  • stream returns nil when the response body ends normally (the scanner reaches the end of input with no error). streamWithReconnect reads a nil error as "stopped on purpose" and returns, so no reconnect is ever tried. SetConnected(false) is not called on that path either, so /.well-known/healthcheck.json keeps reporting ris_live: ok.
  • The HTTP client has no timeout and the read loop no idle limit. A connection that stays open but sends nothing blocks scanner.Scan forever, with the same result.

Failure scenario: RIS Live restarts, or something between it and routewatch closes the long-running response. routewatch stays up and healthy, and its routing table never changes again. The container is never restarted because the health check passes.

Severity: critical

Definition of done

  • Only a cancelled streamer context (Stop) ends streamWithReconnect. A stream that ends for any other reason, with or without an error, counts as a disconnect: the connected flag goes false and the streamer reconnects with the existing backoff.
  • If no line arrives for a set time (a named constant, e.g. 60 seconds; the full feed carries many messages per second), the streamer drops the connection and reconnects.
  • Tests against a local fake server (httptest), no network: (1) the server ends the first response normally, and the streamer reconnects and handles a message from the second response, with the connected flag false in between; (2) the server holds the first response open without sending, and the streamer reconnects after the idle limit (the limit settable in the test so it runs in well under a second).
  • make check passes.

Model: opus-5-5

When RIS Live ends the stream, or the connection stays open but stops sending, routewatch stops receiving updates for good and its health check keeps answering ok. Where: `internal/streamer/streamer.go`, `stream` and `streamWithReconnect`. - `stream` returns `nil` when the response body ends normally (the scanner reaches the end of input with no error). `streamWithReconnect` reads a `nil` error as "stopped on purpose" and returns, so no reconnect is ever tried. `SetConnected(false)` is not called on that path either, so `/.well-known/healthcheck.json` keeps reporting `ris_live: ok`. - The HTTP client has no timeout and the read loop no idle limit. A connection that stays open but sends nothing blocks `scanner.Scan` forever, with the same result. Failure scenario: RIS Live restarts, or something between it and routewatch closes the long-running response. routewatch stays up and healthy, and its routing table never changes again. The container is never restarted because the health check passes. Severity: critical ## Definition of done - Only a cancelled streamer context (`Stop`) ends `streamWithReconnect`. A stream that ends for any other reason, with or without an error, counts as a disconnect: the connected flag goes false and the streamer reconnects with the existing backoff. - If no line arrives for a set time (a named constant, e.g. 60 seconds; the full feed carries many messages per second), the streamer drops the connection and reconnects. - Tests against a local fake server (`httptest`), no network: (1) the server ends the first response normally, and the streamer reconnects and handles a message from the second response, with the connected flag false in between; (2) the server holds the first response open without sending, and the streamer reconnects after the idle limit (the limit settable in the test so it runs in well under a second). - `make check` passes. Model: opus-5-5
clawbot self-assigned this 2026-10-14 14:33:43 +02:00
clawbot added the critical label 2026-10-14 14:33:46 +02:00
Author
Collaborator

#60: only Stop ends the reconnect loop; any other end of the stream marks the feed disconnected and reconnects with the existing backoff, and 60 seconds without a line drops the connection. Two new tests against a local server cover both cases.

Model: opus-5-5

https://git.eeqj.de/sneak/routewatch/pulls/60: only `Stop` ends the reconnect loop; any other end of the stream marks the feed disconnected and reconnects with the existing backoff, and 60 seconds without a line drops the connection. Two new tests against a local server cover both cases. Model: opus-5-5
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/routewatch#53