Skip to content

fix(provider): cancel the pending reconnect on disconnect() and destroy() - #1183

Merged
janthurau merged 1 commit into
ueberdosis:mainfrom
LucaMartinet7:fix/cancel-reconnect-timer
Oct 12, 2026
Merged

janthurau merged 1 commit into
ueberdosis:mainfrom
LucaMartinet7:fix/cancel-reconnect-timer

Conversation

@LucaMartinet7

Copy link
Copy Markdown
Contributor

Fixes #1182

Problem

When an established connection closes, HocuspocusProviderWebsocket.onClose schedules a reconnect with setTimeout, but the handle was dropped. Calling disconnect() or destroy() within delay of the close could not cancel it: the timer called connect(), which set shouldConnect back to true and opened a new socket. After destroy(), nothing listened to that socket or closed it.

Fix

  • Keep the handle in reconnectTimeout.
  • Clear it in disconnect() (which destroy() also calls) and at the start of connect(), so a manual connect() doesn't leave a second one pending.

Tests

Added tests/providerwebsocket/reconnectTimer.ts, based on the reproduction in the issue. For both disconnect() and destroy(), it opens a fake socket, closes it from the server side, tears down within delay, and checks that no second socket is created and shouldConnect stays false. Both cases fail without the fix and pass with it. tests/provider and tests/providerwebsocket pass (73 tests) on Node 22.

…oy()

onClose schedules a reconnect with setTimeout but dropped the handle, so
calling disconnect() or destroy() within `delay` of a close could not stop
it: the timer called connect(), set shouldConnect back to true and opened
a socket nobody asked for.

Keep the timer handle and clear it in disconnect() (which destroy() calls)
and at the start of connect().

Fixes ueberdosis#1182
@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository YAML (base), Organization UI (inherited)
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 787ebf77-f8e7-4394-acb5-78ac182ebfe8
📥 Commits

Reviewing files that changed from the base of the PR and between ee7c6e1 and 3514633.

📒 Files selected for processing (2)
  • packages/provider/src/HocuspocusProviderWebsocket.ts
  • tests/providerwebsocket/reconnectTimer.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review.


📝 Summary

The websocket provider now stores pending reconnect timers and clears them when connect() or disconnect() runs. This prevents a scheduled reconnect from opening a socket after disconnect() or destroy().

New tests check that both teardown methods stop the reconnect and keep shouldConnect false.

Walkthrough

The websocket now tracks delayed reconnects and clears the pending timer during connection setup and disconnect. Tests verify that disconnect() and destroy() prevent a new socket from opening after a close.

Changes

Websocket reconnect cancellation

Layer / File(s) Summary
Track and cancel reconnect timers
packages/provider/src/HocuspocusProviderWebsocket.ts, tests/providerwebsocket/reconnectTimer.ts
The websocket stores the reconnect timer, clears it when it fires, and cancels it in connect() and disconnect(). Tests check that disconnect() and destroy() prevent a second socket from opening.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Suggested labels: complexity: easy, complexity: hard, impact: low

Merge Risk: ⚪ Minimal · up to 35146

No actionable merge-blocking risk remains in the reviewed reconnect cancellation change.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the provider reconnect bug and the cancellation behavior added for disconnect() and destroy().
Description check ✅ Passed The description directly explains the reconnect timer problem, the implementation fix, the affected teardown methods, and the added tests.
Linked Issues check ✅ Passed Issue #1182 requires teardown to prevent a delayed reconnect and keep shouldConnect false. The change stores the onClose() timer in reconnectTimeout, clears it in disconnect(), and clears any …
Out of Scope Changes check ✅ Passed The source changes only manage the reconnect timer. The added tests exercise the two teardown cases from issue #1182. No unrelated behavior or files are changed.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2…
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added complexity: easy Small effort, well-defined scope complexity: hard Multiple components, research needed impact: low No direct user impact labels Oct 8, 2026
@janthurau
janthurau merged commit 52dffba into ueberdosis:main Oct 12, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

complexity: easy Small effort, well-defined scope complexity: hard Multiple components, research needed impact: low No direct user impact

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HocuspocusProviderWebsocket: disconnect() or destroy() within delay of a close is undone by the reconnect timer

2 participants