Repository navigation
Conversation
… session resumes A new gateway connection cleared the whole send queue, so a subscription queued while the socket was down (or not yet written when it dropped) was lost while Watched.sent already named it, and RESUMED never said it again. A resumed connection now keeps the unwritten, coalesced subscriptions (commands are still dropped, and a new session still starts empty), and RESUMED says what is on screen once more in case a frame written as the socket died never arrived. Fixes #42 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner
Author
|
@vbmithr this one fixes the queue-loss case you reproduced in #42. What changed:
Tests:
Not covered: a guild unsubscribe that was already written but lost with the socket isn't sent again. Only the current subscription is repeated on resume. Fixing that would mean tracking per guild what Discord actually received. To try it: git fetch origin pull/50/head:pr-50 && git checkout pr-50
cargo test -p chatd --test discord member_viewport_changed_while_offline
cargo test -p chatd adapters::discord::gateway
cargo test -p chatd # full daemon suiteIf you still have your local audit test, running it against this branch would be a useful second check. So would a real suspend/resume with the member pane open. |
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.
Cause
members.rs::subscriberecordsWatched.sentwhen a subscription is queued, not when it is written.gateway.rs::runcleared the whole outbox on every new connection, so a subscription queued while offline, or still unwritten when the socket dropped, was thrown away. Becausesentalready named it, later identical Watches were deduplicated, andRESUMEDnever re-sent anything. The session resumed with Discord still holding the old viewport, and the member pane stayed pending.Fix
SendQueue::reconnected(resuming): when the new connection resumes an existing session, keep the coalesced subscriptions that were never written and drop only the commands. That coalesced map is exactly the change from what Discord last received to what is on screen now, including the unsubscribe from an old guild. A connection that identifies a new session still clears everything, as before.RESUMED,resubscribe()sends the current subscription again (subscribe(true)), because a frame written just as the socket died may never have reached Discord. This costs one frame per resume and merges with any kept snapshot.Nothing changes for READY or identify, so this should stay clear of #43 and #44.
Validation
member_viewport_changed_while_offline_is_delivered_after_resumeincrates/chatd/tests/discord.rs, not ignored. It subscribes to 4101, drops the socket, sends a Watch for 4105 while offline, waits for the resume, then asserts that an op 37 for 4105 arrives after the op 6 resume frame and that the member cache fills from a SYNC. It fails on main and passes with this change.a_resumed_connection_keeps_unwritten_subscriptions_and_a_new_session_does_not.cargo test -p chatd: all passing. 135 lib unit tests, plus integration tests: blobs 14, calls 10, discord 31, e2e 25, messages 5, playback 4, polish 12, signal 10, slack 15, teams 7, telegram 17, upload 5. Total 290 passed, 0 failed, 0 ignored.Fixes #42
🤖 Generated with Claude Code