fix(observer): seed SSE revision persistently and fence closed-server loops - #111
Merged
Conversation
… loops - persist the SSE revision in a new sse_state table so a restarted sidecar seeds its revision hub from the stored value (Last-Event-ID cursors stay monotonic across restarts) - fail closed when canonical readback fails: _last_canonical_ok_at is invalidated so cursor_valid cannot keep LIVE on thread liveness alone - stop the SSE serve loop once the server is closed (no more heartbeats after store shutdown) and reject new /api/v1/events connections with 503
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
WL3-600 persistent-SSE hardening — three real P0 gaps on current
main(
9090da6), each with a failing-test-then-fix (RED→GREEN):P0-1 — canonical readback failure no longer keeps LIVE
_last_canonical_ok_atis now invalidated (None) when the canonicalfingerprint readback raises, so
cursor_validcannot stayLIVEon threadliveness alone. Test:
test_failing_canonical_readback_removes_live.P0-2 — SSE revision is persistent across restarts
New
sse_statetable (schema migration v3) +CanonicalStore.record_revision();seed_revision()preferssse_state.last_revision. A restarted sidecar nowseeds
SseRevisionHubfrom the stored revision, keepingLast-Event-IDcursors monotonic instead of resetting the sequence to 1.
P0-3 — SSE serve loop fenced by server closure
/api/v1/eventsreturns 503 once the server is closed, and the serve loopbreaks out of its heartbeat cycle on
server._closed— an old handler can nolonger refresh
_last_heartbeat_at(or touch a closed store) after shutdown.Test:
test_sse_handler_loop_stops_after_server_close(also cleans up theWindows serve_forever select noise with an explicit
shutdown()).Verification
test_sidecar_v3_snapshot.py+test_snapshot_sse_live.py: 50 passed, 7 subtests passed, 0 warningstests/ci/test_aggregate_gate.py+test_governance_gate.py: 17 passedpy_compileclean on all three modified scripts