Repository navigation
pool: tell a subscription when it may have missed events (macula-station#129) - #64
Merged
Merged
Conversation
…a-station#129) When the last link carrying a subscription ended, the pool redialed and subscribed again in silence, so whatever the station sent to the ended link was gone without a word (craft-collab#38). Events() now delivers pool.Delivery: an event, or KindInterrupted once when the last covering link ends (from its last heard, for its end reason) and KindGap once when a station accepts the subscription again, before any event of that link. Nothing while another link covers it, for an outage the link survives, or at the first subscribe; a notice is never dropped for a full subscription. stationlink gains Link.LastHeard and EndReason; the C ABI inbox gives every item a "kind"; teststation gains Silence, a path outage the connection survives, which the live tests use (phase 1 spec, issuecomment-6527386000). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…129) Close cancels the pool's context, then ends its links; each link's end read as the last covering link ending and delivered an Interrupted before the subscription closed, which the C ABI test caught. A subscription whose context ended owes no notice. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
open() handed a notice back to notify, which for a group subscription sends to opening again, so open read it forever: no Interrupted or Gap ever reached Events and open spun. open now pushes a notice straight to Events; notify keeps choosing the next stage for attach and forward. A link accepted before an ended link's forward recorded its end found the set still covered and owed nothing; attach now records every covering link that already ended first. README: a Gap can push out an unread Interrupted on a full buffer, and a group's notice waits behind events still being opened. Refs macula-io/macula-station#129 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Purpose (reliability): an application reading a subscription is told, in-band, when the connection to its stations dropped long enough for events to be lost, instead of reading on as if nothing happened.
Refs macula-io/macula-station#129 (phase 1 spec: https://github.com/macula-io/macula-station/issues/129#issuecomment-6527386000). Stacked on #63 (macula-go#62), whose 300 s teststation the live tests rely on; it retargets to master once #63 merges.
What changes
Subscription.Events()deliverspool.Delivery(breaking, next minor):KindEvent(Delivery.Event),KindInterruptedonce when the last link carrying the subscription ends (FromMs= that link's last heard,Reason= its end reason),KindGaponce when a station accepts it again, before any event of that link (FromMs..ToMs).pool/delivery.go): a link covers a subscription from its accepted REGISTER_ACK until the link ends. Nothing while another link covers it, for an outage the link survives, at the first subscribe, or after Unsubscribe/Close. A refused re-subscribe leaves it interrupted with no Gap.Dropped). The C ABI inbox follows the same rule, and every item gets"kind":event,interrupted(from_ms,reason),gap(from_ms,to_ms,reason).stationlink.Link.LastHeard,stationlink.EndReason(liveness_lost,closed,goodbye,status_expired,binding_expired,malformed_frame,idle_timeout,closed_by_station,connection_lost).teststation.Station.Silence: a path outage QUIC keeps the connection through; what falls in it is lost.Tests (the spec's shape, against the teststation)
TestAnOutagePastLivenessDeliversAnInterruptedThenAGap: 90 s silence, one Interrupted (liveness_lost, from <= silence start + 1 s), then one Gap before any event of the new link, while events are published every 20 ms across the ack (~91 s).TestOneOfTwoLinksEndingDeliversNoNoticeTestBothLinksEndingAndOneReturningDeliversOneOfEachTestAShortOutageTheLinkSurvivesDeliversNoNotice: 10 s silence, 45 s watched, same link after (~47 s).TestARefusedResubscribeDeliversNoGapTestUnsubscribingWhileInterruptedDeliversNothingMore(7 is Erlang-only.) Unit tests cover the coverage set (empty, refilled, simultaneous ends, a link that ends before its ack),
EndReason,LastHeard, and the C ABI notice JSON and full-inbox rule. Cases 1 and 4 run in parallel.🤖 Generated with Claude Code