feat(sync): re-arm the open channel's subscription first on reconnect - #127
Merged
Conversation
A reconnect re-REQs every standing subscription, and the engine keeps one per joined channel. Until now that walk took `Dictionary`'s order, so the conversation a reader was actually looking at could be restored last and its channel stayed silent for the whole replay — most visible on foregrounding, which is where most reconnects happen. `SubscriptionManager` gains an advisory priority: one subscription id armed ahead of the rest. `SyncEngine.setActiveChannel(_:)` names the channel on screen, and `subscribeChannelContent(_:)` claims the priority when it registers a channel that is already open — a conversation can be on screen before discovery has subscribed it. `ChannelTimelineView` reports itself on appear. Ordering only: filters, membership and delivery are untouched, and a stale id is skipped rather than stranding the walk, so nothing has to clear it.
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.
What
A reconnect re-
REQs every standing subscription, and the engine keeps one per joined channel. Until now that walk tookDictionary's order, so the conversation a reader had open could be restored last — and its channel stayed silent for the whole replay. Most visible on foregrounding, which is where most reconnects happen.The open channel now goes first.
How
SubscriptionManagergains an advisory re-arm priority — one subscription id armed ahead of the rest (prioritise(_:)), consumed by a newarmOrder()inhandleReadinessChange.SyncEngine.setActiveChannel(_:)names the channel on screen.subscribeChannelContent(_:)claims the priority when it registers a channel that is already open — a conversation can be on screen before discovery has subscribed it, and opening one is itself a route into that method.ChannelTimelineViewreports itself in a.task.Ordering only: filters, membership and delivery are untouched. A stale id — its subscription unsubscribed or closed by the relay — is skipped rather than stranding the walk, so nothing has to clear it. The priority is deliberately not cleared when a conversation closes: the channel just left is the one most likely to be reopened.
Ports the visible-first half of upstream block/buzz#3053. The pacing/rate-limit-gate half of that PR is not included here — see the note below.
Validation
swift test -c release)swift test -c release)The new ordering test was checked against the negative. Swift seeds dictionary hashing per process, so a single green run proves nothing about ordering. With
armOrder()reverted toArray(subscriptions.keys)the test failed 7 of 8 runs; with the fix, 8 of 8.Two tests only, per the owner's request to keep coverage proportionate: the ordering itself, and a stale-priority case so a closed subscription cannot strand the re-arm walk.
Not in scope
The rate-limited-
CLOSEDretry gap (handleClosed'sdefault:branch drops a.retryableclose) is real but separately tracked: the engine already self-heals through the directory refresh, and at 16 channels against the relay's 50 REQ/5s budget it is latent. That work is a gate plus bounded backoff and wants its own change.