You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Reconcile queued Discord member subscriptions after gateway session resume #42
A reconnect can discard an unsent Discord member subscription while retaining local state that says the subscription was already sent. A successful session resume does not reconcile that state, potentially leaving the member pane pending even though the gateway is connected.
Relevant paths in crates/chatd/src/adapters/discord/:
members.rs::subscribe assigns Watched.sent when enqueueing the desired subscription, before the gateway actually writes it.
gateway.rs::run clears the outbox when a new gateway connection is established.
On RESUMED, ready.rs::resumed restores cached presence but does not requeue/reconcile the current member subscription.
An unchanged Watch is ignored, and an identical desired subscription is deduplicated against Watched.sent.
A concrete failure sequence is: queue a viewport subscription, lose the connection before sending it, clear the queue on reconnect, then successfully resume. Discord may retain the earlier viewport while chatd considers the discarded newer viewport subscribed. Repeated cache reads do not repair this mismatch.
Observed symptom during member-pane investigation: occasional initial loading skeletons lasting seconds, with immediate Members cache replies containing pending: true, no groups and no rows. Laptop suspend/network loss was also observed. The causal connection between that live symptom and this code path has not yet been reproduced or confirmed. Merely resuming a session with an already-delivered subscription is not evidence of failure.
Expected behavior: after resume, reconcile the latest desired viewport with what was actually delivered. Preserve or regenerate discarded subscription state without treating queued frames as acknowledged subscriptions. Handle obsolete roster data consistently when the viewport changed while offline.
Suggested regression coverage: interrupt the connection with a subscription still queued, resume the existing session, and verify that the latest viewport is delivered and its member cache can fill. Include viewport changes while disconnected.
Related: #40 introduces viewport-driven member caching and coalesced subscription snapshots. This issue tracks reconnect recovery separately; #40 explicitly does not claim to resolve intermittent initial loading.
The standalone daemon audit now reproduces the queue-loss failure, rather than only identifying a possible code path.
Tested main 44ad327 plus #40 (6fa84d4), using the real release chatd binary with temporary synthetic account data and local fake Discord HTTP/WebSocket servers. No GUI or real account participated.
Reproduction:
Subscribe to channel A and wait for its subscription to reach the fake Gateway.
Drop the Gateway TCP connection and wait for the account to become Offline.
While offline, send Watch selecting channel B and its first 50 members.
Allow the existing session to resume and wait for Connected.
Inspect subscriptions delivered to the Gateway.
Observed: no subscription for B arrives within 500 ms after resume. The explicit regression member_viewport_changed_while_offline_is_delivered_after_resume fails with “resumed gateway never received the viewport selected while offline” in 2.74 seconds overall. The 500 ms deadline does not measure eventual recovery. The test currently exists locally and is explicitly ignored in the ordinary suite pending a fix.
This confirms the controlled failure sequence described here. Whether it caused a particular earlier live blank-pane incident remains unconfirmed. The existing dropped-socket integration test passes because it checks session resume, messages, presence and heartbeats without changing the member viewport while disconnected.
Activity
vbmithr commentedon Oct 18, 2026
The standalone daemon audit now reproduces the queue-loss failure, rather than only identifying a possible code path.
Tested main
44ad327plus #40 (6fa84d4), using the real release chatd binary with temporary synthetic account data and local fake Discord HTTP/WebSocket servers. No GUI or real account participated.Reproduction:
Observed: no subscription for B arrives within 500 ms after resume. The explicit regression
member_viewport_changed_while_offline_is_delivered_after_resumefails with “resumed gateway never received the viewport selected while offline” in 2.74 seconds overall. The 500 ms deadline does not measure eventual recovery. The test currently exists locally and is explicitly ignored in the ordinary suite pending a fix.This confirms the controlled failure sequence described here. Whether it caused a particular earlier live blank-pane incident remains unconfirmed. The existing dropped-socket integration test passes because it checks session resume, messages, presence and heartbeats without changing the member viewport while disconnected.
fix: deliver a Discord member viewport chosen while offline after the…
fix: deliver a Discord member viewport chosen while offline after the…