Skip to content

fix(qqbot): prevent silent busy-loop when reconnect fails - #20994

Closed
lijinxiao1982 wants to merge 1 commit into
NousResearch:mainfrom
lijinxiao1982:fix/qqbot-reconnect-busy-loop
Closed

fix(qqbot): prevent silent busy-loop when reconnect fails#20994
lijinxiao1982 wants to merge 1 commit into
NousResearch:mainfrom
lijinxiao1982:fix/qqbot-reconnect-busy-loop

Conversation

@lijinxiao1982

Copy link
Copy Markdown

Problem

When _reconnect() fails (e.g. DNS resolution error on api.sgroup.qq.com), self._ws was left pointing to the stale closed WebSocket. _read_events() would detect ws.closed=True and return immediately without raising an exception, causing _listen_loop to reset backoff_idx=0 on each iteration — an infinite tight loop with no reconnect attempts and no log output.

Fix

Clean up self._ws in the _reconnect() failure path so _read_events() raises RuntimeError on next call, triggering the proper backoff retry logic.

Testing

Reproduced on a production gateway (DNS fluctuation caused 78+ minute outage). Applied fix, restarted, QQ Bot reconnected normally.

When _reconnect() fails (e.g. DNS resolution error), self._ws was left
pointing to the stale closed WebSocket.  _read_events() would detect
ws.closed=True and return immediately without raising an exception,
causing _listen_loop to reset backoff_idx=0 on each iteration — an
infinite tight loop with no reconnect attempts and no log output.

Clean up self._ws in the failure path so _read_events() raises
RuntimeError('WebSocket not connected'), which triggers the proper
backoff retry logic in _listen_loop.
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists platform/qqbot QQ Bot adapter comp/gateway Gateway runner, session dispatch, delivery labels May 7, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Automated hermes-sweeper review: this busy-loop fix is already implemented on current main.

Evidence:

  • gateway/platforms/qqbot/adapter.py:684 now raises RuntimeError("WebSocket closed") when _read_events() enters with a closed-but-non-None websocket, avoiding the normal return that reset reconnect backoff.
  • gateway/platforms/qqbot/adapter.py:493 shows _listen_loop only resets backoff_idx after _read_events() returns normally, so the new exception path triggers reconnect/backoff instead.
  • tests/gateway/test_qqbot.py:2201 adds a regression test for the closed-websocket guard and documents the 100% CPU busy-loop case.
  • The fix landed in 3eeca4613d618618093db416b564a2b9ef8dbe6a via PR fix(qqbot): stop 100% CPU spin when WebSocket is closed but not None (#31193, #31771) #40574.

@teknium1 teknium1 closed this Jun 11, 2026
@teknium1 teknium1 added the sweeper:implemented-on-main Sweeper: behavior already present on current main label Jun 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/qqbot QQ Bot adapter sweeper:implemented-on-main Sweeper: behavior already present on current main type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants