You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: recover device Realtime channel from half-open socket on reconnect (#520)
* fix: recover device Realtime channel from half-open socket on reconnect
After idle / wifi-loss / sleep the device's Supabase Realtime socket can go
half-open (conn.readyState stays OPEN but the peer is gone). recreateChannel()
removed the old channel un-awaited and synchronously pushed a new one, so the
channel registry never reached 0, realtime-js never tore the dead socket down,
and every re-subscribe TIMED_OUT forever -- only a process restart recovered.
Fix (remote-channel.ts):
- recreateChannel(): add a re-entrancy guard, await removeChannel(), and force a
fresh WebSocket via realtime.disconnect() before re-subscribing.
- checkConnectionHealth(): treat 'joining' as healthy so realtime-js's own rejoin
backoff can converge instead of being torn down mid-join.
Also enrich the existing reconnect/timeout logs with a compact connState() line
(socket state + readyState + channel state + attempt), turn on the previously
commented-out CHANNEL_ERROR log, and add a CLOSED branch.
Add test/remote-channel-reconnect.test.ts -- a deterministic repro that fails on
the old behavior (8x TIMED_OUT, dead socket reused) and passes with the fix.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test+fix: address PR #520 review (timeout-guard recreate, settle CLOSED, suite-native test)
- recreateChannel(): wrap the awaited section in a 30s timeout (Promise.race,
mirrors closeWithTimeout) so a never-settling await can't pin
isRecreatingChannel=true and silently disable the 10s watchdog.
- createChannel() CLOSED branch: reject() (was un-settled -> could hang the
recreate) and setOnlineStatus('offline') for parity with CHANNEL_ERROR/TIMED_OUT.
- Rewrite the repro test as test/test-remote-channel-reconnect.js (plain JS,
imports compiled dist, runs under node) so run-all-tests.js discovers it and it
runs in `npm test` -- no runner/package.json special-casing. Removes the tsx-only
.ts version. Adds a 'joining is treated as healthy' case.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
0 commit comments