Skip to content

feat(sync): re-arm the open channel's subscription first on reconnect - #127

Merged
jtvargas merged 1 commit into
mainfrom
feat/visible-first-rearm
Aug 3, 2026
Merged

feat(sync): re-arm the open channel's subscription first on reconnect#127
jtvargas merged 1 commit into
mainfrom
feat/visible-first-rearm

Conversation

@jtvargas

@jtvargas jtvargas commented Aug 3, 2026

Copy link
Copy Markdown
Owner

What

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 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

  • SubscriptionManager gains an advisory re-arm priority — one subscription id armed ahead of the rest (prioritise(_:)), consumed by a new armOrder() in handleReadinessChange.
  • 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.
  • ChannelTimelineView reports 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

  • NostrCore: 309 tests, 36 suites — all passed (swift test -c release)
  • BuzzKit: 558 tests, 99 suites — all passed (swift test -c release)
  • Device build installed and launched on an iPhone 17 Pro Max; owner confirmed the behaviour.

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 to Array(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-CLOSED retry gap (handleClosed's default: branch drops a .retryable close) 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.

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.
@jtvargas
jtvargas merged commit bd95394 into main Aug 3, 2026
6 checks passed
@jtvargas
jtvargas deleted the feat/visible-first-rearm branch August 3, 2026 20:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant