Skip to content

test(slack): cover the task rebound during Socket Mode teardown - #1

Open
topseon23 wants to merge 1 commit into
RelaxJonh:fix/slack-socket-mode-orphan-task-drainfrom
topseon23:slack-orphan-drain-regression-test
Open

test(slack): cover the task rebound during Socket Mode teardown#1
topseon23 wants to merge 1 commit into
RelaxJonh:fix/slack-socket-mode-orphan-task-drainfrom
topseon23:slack-orphan-drain-regression-test

Conversation

@topseon23

Copy link
Copy Markdown

Adds the regression test I offered in NousResearch#83693 (comment). Test only — no production code touched.

Why

The drain in NousResearch#83693 has no test, and this failure is easy to pin. The fake client here rebinds current_session_monitor while close() is awaiting, which is what connect() does on success, so the task appears after the adapter's pre-close snapshot was taken — the exact window the drain exists to cover.

What it asserts

The production symptom is unbounded growth, not one stray retry, so the meaningful assertion is that the closed-session retry counter stops moving:

before = client.aiohttp_client_session.ws_connect_after_close
await asyncio.sleep(0.05)
after = client.aiohttp_client_session.ws_connect_after_close
assert after == before

AsyncSocketModeHandler defaults to ping_interval=10 and connect()'s except branch sleeps exactly that between retries, so one wedged loop is ~6 log lines/min until the process restarts. We saw 6/min and 12/min (one and two orphans) in two separate windows, matching the count of preceding Socket Mode unhealthy (...); reconnecting events.

Verification

Against this branch:

  • with the drain: 4 passed
  • with the drain disabled: the new test fails, leaving Task pending ... connect() running — i.e. it does guard the fix rather than passing either way

Feel free to squash it into your branch instead of merging the PR if that is easier.

Guards the drain added in NousResearch#83693. Without it the rebound task is left as
`Task pending ... connect() running` and keeps retrying against the closed
shared session; with it teardown cancels the task and the retries stop.

The production symptom is unbounded growth rather than one stray retry, so the
test asserts that the closed-session retry counter stops moving, not just that
the task was cancelled. `AsyncSocketModeHandler` defaults to `ping_interval=10`
and `connect()`'s except branch sleeps exactly that between retries, so a single
wedged loop is roughly 6 log lines per minute until the process restarts.

The fake client rebinds `current_session_monitor` while `close()` is awaiting,
which is what `connect()` does on success, so the task appears after the
adapter's pre-close snapshot was taken.

Refs NousResearch#46990.
altjs4510 pushed a commit to altjs4510/hermes-agent that referenced this pull request Aug 24, 2026
Upstream PR NousResearch#83693 fixes the same bug by re-reading the
client task attributes after close_async(). Once it merges, drop this local
sweep and take theirs — the fork diff on this file is already wide and the only
behavioural difference (reachability-independent vs attribute re-read) is not
worth carrying alone. Raised on the PR instead.

Our rebind-window regression test is offered upstream as RelaxJonh#1.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant