Skip to content

feat(websocket): freshness-based health check with disconnect reason#7

Merged
kevinypfan merged 2 commits into
release/v1.5.0from
feat/healthcheck-freshness
Jul 1, 2026
Merged

feat(websocket): freshness-based health check with disconnect reason#7
kevinypfan merged 2 commits into
release/v1.5.0from
feat/healthcheck-freshness

Conversation

@kevinypfan

Copy link
Copy Markdown
Collaborator

What

Reworks the WebSocket health check from a "blind send-counter + silent disconnect" to freshness-based detection, keeping the existing app-level JSON ping/pong transport (browser-compatible via isomorphic-ws — no protocol-level frames).

Behavior

  • Track lastMessageAt, updated on any inbound message (not just pong); lastPingAt set when a health-check ping is sent.
  • Each interval: if nothing arrived since the last ping → a MISS (increment consecutive-miss counter), else reset to 0. On reaching maxMissedPongs → disconnect and stop the timer; otherwise send ping.
  • On health-check timeout the disconnect event carries a 2nd arg { reason: 'health-check-timeout' }; normal/manual disconnects emit it with no 2nd arg. Non-breaking for single-arg listeners.
  • Config unchanged (enabled default false, pingInterval 30000, maxMissedPongs 2). No auto-reconnect; does not use the error event.

Tests / docs

  • Rewrote the Health Check test block + added cases (freshness reset, consecutive misses, timeout reason payload, manual/server close). npm test → 147/147.
  • README: new Health Check section with a reconnect-on-timeout example.

🤖 Generated with Claude Code

kevinypfan and others added 2 commits June 22, 2026 17:30
Replace the blind missed-pong counter with freshness-based detection:
track lastMessageAt (any inbound message) and lastPingAt, and on each
interval tick count a miss only when nothing arrived since the last ping.
Disconnect after maxMissedPongs consecutive misses and stop the timer.

On a health-check timeout the disconnect event now carries a second
argument { reason: 'health-check-timeout' }; normal/manual disconnects
emit no second argument, keeping existing single-arg listeners working.
Keeps the app-level JSON ping/pong transport (no protocol-level frames).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A value of 0 would disconnect a healthy connection on the first tick
(consecutiveMisses starts at 0 and 0 >= 0). Clamp to >= 1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kevinypfan kevinypfan changed the base branch from master to release/v1.5.0 July 1, 2026 09:23
@kevinypfan kevinypfan merged commit 6249384 into release/v1.5.0 Jul 1, 2026
4 checks passed
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