Full Outbox Implementation#1493
Conversation
Changelog-Added: Add the routed relay outbox runtime for subscriptions, fetches, publishes, and full-history sync
Changelog-Fixed: Prevent relay-list discovery from stalling when one relay never sends EOSE
Changelog-Fixed: Avoid dropping timeline notes when NDB visibility lags subscription polling
Changelog-Fixed: Keep visible profile and note lookups pending until their fetch batch is sent
Changelog-Fixed: Clear one-shot fetch relay legs as each relay finishes instead of waiting for every relay
Changelog-Changed: Show active relay inventory with stable virtualized rows
Changelog-Fixed: Prevent relay expansion from saturating websocket connection attempts
Changelog-Fixed: Fetch visible missing profiles through outbox routing with normal read priority
Changelog-None:
Changelog-None:
|
Important Review skippedToo many files! This PR contains 183 files, which is 33 over the limit of 150. To get a review, narrow the scope: Upgrade to a paid plan to raise the limit. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (183)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This PR moves Notedeck’s relay/outbox backend from a UI-frame-driven model to an async bridge-owned runtime.
Previously,
Notedeck::tickdirectly advancedOutboxPool: relay receive, keepalive, NIP-11, full-history maintenance, scoped-sub realization, one-shot fetches, publish work, and NDB ingestion all shared the frame loop boundary. This PR replaces that with a remote bridge: UI code submits typed remote intents, the bridge owns outbox execution, and the UI consumes committed facts through a read model.Also, the app now starts under an explicitly sized Tokio runtime instead of relying on #[tokio::main], so Notedeck can reserve threads deliberately: one for UI, one for the outbox bridge, a small fixed job pool for synchronous work, and the remainder for app async tasks.
What changed
Adds a bridge-owned async outbox runtime.
RemoteApinow batches scoped-sub, fetch, publish, and account-change intents.RemoteBridgeserializes those intents, drivesOutboxService, and emits committedOutboxEvent/ScopedSubFactupdates back to the UI thread.RemoteOutboxReadModelbecomes the UI-side source for relay status, request status, and sub EOSE state.Splits outbox protocol state from outbox execution.
OutboxPoolretains subscription/coordinator state.OutboxServiceowns transport, websocket admission, reconnects, NIP-11, full-history, negentropy, multicast, and async capability completion.Reworks scoped subscriptions around the new backend.
SubConfignow describes the intended execution mode: selected account read relays, explicit relays, selected account read plus explicit coverage, or selected account read plus author-outbox augmentation.Adds author-outbox routing for eligible Columns timeline/thread subscriptions.
Moves full-history / negentropy work into the async runtime.
Updates transient fetches, UnknownIds, and profile fetch behavior for the new model.
Adds websocket admission and user-configurable connection limits.
Migrates app surfaces to the new remote APIs.
User-visible effect
Large timeline and thread loads now run through an async outbox backend instead of depending on the UI frame to advance relay work. The app can keep rendering while relay connections, NIP-11, full-history, EVENT ingestion, and scoped-sub routing progress in the bridge.
When outbox relays are enabled, timeline and thread subscriptions can use additional relay coverage from author relay lists and observed relays. When disabled, those paths stay on selected account read relays.
The relay connection limit setting is now enforced by the backend, and the relay view reflects the same committed websocket state as the sidebar indicator.