fix(discord): close stale client before reconnect to prevent zombie websocket (#18187)#18297
Closed
Bartok9 wants to merge 1 commit into
Closed
Conversation
…ebsocket (NousResearch#18187) On gateway restart or reconnect, connect() was called a second time without closing the previous commands.Bot instance. Discord does not immediately terminate the old websocket, leaving two live connections simultaneously. Both connections delivered every inbound event independently, bypassing MessageDeduplicator (race condition between two concurrent on_message coroutines) and spawning two separate agent turns per message. Fix: before instantiating a new commands.Bot, await the old client's close() if it exists and is not already closed, then clear _ready_event. This ensures only one Discord websocket connection is ever active for the adapter. Verified by code inspection: disconnect() at line ~779 already calls await self._client.close() for graceful shutdown; this change mirrors that guard in the reconnect path.
Collaborator
Collaborator
|
Likely duplicate of #18224 |
Contributor
Author
|
Thanks @alt-glitch — confirmed superseded by #18224 which covers the same Discord zombie-websocket fix. Closing. |
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.
Problem
On gateway restart or adapter reconnect,
connect()created a newcommands.Botinstance without closing the previous one. Discord's gateway does not immediately terminate an orphaned websocket — both the old and new client remain live for a window of time. During that window, every inbound event is delivered to both connections independently.MessageDeduplicatorcannot prevent this because the twoon_messagecoroutines may checkis_duplicatebefore either has marked the ID as seen (race condition). The result: two separate agent turns are spawned per message, each producing a different response.With
auto_thread: truethis is especially visible: one response lands in the thread (correct path) and a second response lands in the parent channel (incorrect path).Fix
Before instantiating a new
commands.Bot, await the old client'sclose()if it is not already closed, then clear_ready_event:This mirrors the guard already present in
disconnect()(~line 779) and ensures only one Discord websocket is ever active for the adapter at any time.Testing
auto_threadmode: only one response appears in the thread, no response leaks to the parent channelconnect()call on first start: no change in behavior (self._clientisNone, guard is a no-op)Closes #18187