When a client resumes a request stream with Last-Event-ID, the replayed stream stays open indefinitely (keep-alive now keeps it healthy) even when every correlated response has already been delivered or stored.
Three narrow races follow from this:
- A response that becomes store-visible while a resume is mid-flight is missed by that replay's snapshot and never delivered to the now-permanent successor.
- A superseded successor's dedup state does not transfer, so a double reconnect during an in-flight store write can double-deliver a response.
- A stream resumed after
closeSSEStream polling delivers the replayed response but never ends.
Closing a replayed request stream after replay whenever no in-flight requests map to it turns the polling loop into one that converges: the client re-polls until a replay snapshot includes the response.
Applies to both main and v1.x (the send()/replay code has the same shape in both). Split out from the review discussion on #2547.
When a client resumes a request stream with
Last-Event-ID, the replayed stream stays open indefinitely (keep-alive now keeps it healthy) even when every correlated response has already been delivered or stored.Three narrow races follow from this:
closeSSEStreampolling delivers the replayed response but never ends.Closing a replayed request stream after replay whenever no in-flight requests map to it turns the polling loop into one that converges: the client re-polls until a replay snapshot includes the response.
Applies to both main and v1.x (the send()/replay code has the same shape in both). Split out from the review discussion on #2547.