Skip to content

Raise RPC WebSocket ping interval to prevent reconnect loop on large workspaces#3500

Open
mincua wants to merge 1 commit into
pingdotgg:mainfrom
mincua:fix/rpc-ws-ping-timeout-large-workspace
Open

Raise RPC WebSocket ping interval to prevent reconnect loop on large workspaces#3500
mincua wants to merge 1 commit into
pingdotgg:mainfrom
mincua:fix/rpc-ws-ping-timeout-large-workspace

Conversation

@mincua

@mincua mincua commented Jun 22, 2026

Copy link
Copy Markdown

What Changed

Raise the Effect RPC client WebSocket ping interval from 5s to 45s, via the existing effect patch (patches/effect@4.0.0-beta.78.patch).
One-line keepalive change; no source or behavior changes beyond the ping cadence.

Why

Opening a thread on a large workspace drops the app into an endless WebSocket disconnect/reconnect loop, and the thread never becomes usable.

The Effect RPC client pinger (makePinger in effect's dist/unstable/rpc/RpcClient.js) pings every 5s and tears down the transport if the peer
doesn't answer within that window. Opening a thread keeps the server event loop busy for ~10–15s — per-project VCS/git status, repository detection,
and favicon resolution across every sidebar project (scales with project count and repo size). The server misses the ping, the client declares the
transport dead and reconnects, the reconnect restarts the same heavy load, the next ping is missed, and it loops.

Confirmed from logs: each WS session ends clean-client-closed with aliveMs ≈ 13000, roughly one per ~13–26s; the client side reports
ConnectionTransientError reason:"transport" at ~10s, repeatedly. The backend PID stays stable (not a process restart) and the establishment /
socket-open timeouts are never reached — only the 5s ping is. Raising it to 45s lets the connection survive a busy-but-alive backend.

A more thorough fix would keep the event loop responsive during thread load (cache/dedup the per-project VCS detection and favicon resolution, and
bound concurrent git spawns) and/or expose the ping interval as a makeProtocolSocket option upstream in Effect instead of hard-coding it in a
vendored patch. Happy to take it in either direction.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes — N/A, no UI changes
  • I included a video for animation/interaction changes — N/A

Note

Medium Risk
Changes keepalive behavior for all Effect RPC WebSocket clients monorepo-wide; slower ping failure detection trades off against fewer false disconnects on a loaded backend.

Overview
Updates the vendored effect@4.0.0-beta.78 pnpm patch so the RPC socket client’s makePinger loop waits 45 seconds between pings instead of 5 seconds, giving the server more time to answer while the event loop is busy (e.g. heavy thread/workspace load) before the client treats the transport as dead and reconnects.

The patch refresh also carries the repo’s other RpcClient customizations (request/connection hooks, ping-timeout handling) and pnpm-lock.yaml is updated so every workspace consumer picks up the new patch hash.

Reviewed by Cursor Bugbot for commit 01bf240. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Raise RPC WebSocket ping interval from 5s to 45s to prevent reconnect loops on large workspaces

  • Increases the heartbeat ping interval in RpcClient.makeProtocolSocket from 5 seconds to 45 seconds, preventing frequent reconnects on large workspaces where ping/pong round-trips may take longer.
  • Adds an optional onPing hook via a new ConnectionHooks context tag, allowing callers to run an effect before each ping is sent.
  • Exports ConnectionHooks and layerHook from the RpcClient module so consumers can register hooks at the call site.
  • The returned socket object now includes a reset function (exposed as latch.await) alongside timeout.

Macroscope summarized 01bf240.

…workspaces

The Effect RPC client pinger (makePinger in effect's RpcClient) pings every 5s
and tears down the WebSocket if the peer does not answer within that window. On
a large workspace, opening a thread keeps the server event loop busy for ~10-15s
(per-project VCS/git status, repository detection, and favicon resolution across
every sidebar project), so the server misses the ping, the client drops the
transport and reconnects, the reconnect restarts the same heavy load, the next
ping is missed, and the connection loops indefinitely — the thread never opens.

Raise the ping interval to 45s via the existing effect patch so the connection
survives a busy-but-alive backend.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 22, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 0148dc55-c6eb-4645-973e-e54a430434b5

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jun 22, 2026
@macroscopeapp

macroscopeapp Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved

This PR makes a single, clear timing change - raising the WebSocket ping interval from 5 to 45 seconds to fix reconnect loops. The lockfile changes are mechanical hash updates from the patch modification. Low-risk configuration tweak with clear bug-fix intent.

You can customize Macroscope's approvability policy. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant