Skip to content

fix(host): close a client socket at its backpressure limit instead of dropping frames - #446

Merged
iamnbutler merged 2 commits into
mainfrom
stale-run
Oct 15, 2026
Merged

iamnbutler merged 2 commits into
mainfrom
stale-run

Conversation

@iamnbutler

Copy link
Copy Markdown
Contributor

Fixes #443.

The channel sends a run's end, but the app never gets it. Bun's ServerWebSocket.send silently drops a frame once a socket has more than 16 MB queued (backpressureLimit defaults to 16 MB and closeOnBackpressureLimit to false). Desktop runs relay screenshot results to a renderer that reads slowly while it draws them, so the queue fills. Whatever arrives after that is lost: the run end (the Stop button stays) or a request's reply (the composer spinner stays). Switching channels re-watches and rebuilds the state, which is why that clears it.

  • The gateway's sockets now close at the limit, and the app's GatewayClient reconnects and re-watches. The limit goes up to 128 MB so ordinary replays heavy with screenshots don't hit it.
  • Checked:
    • A standalone Bun server and a client that doesn't read: with the defaults, sends return 0 (dropped) past 16 MB. With the new options the socket closes with 1006.
    • An isolated loopback host on Sonnet 5.5 (12 large-output shell calls, then 10 image reads totalling 7.7 MB plus a channel tool call): the channel delivered every run end, so the loss is in the gateway relay.
    • Canary's D6 logs: the gateway's changes requests took 200–580 ms while the worker served them in 30–60 ms, which is the backlog.
  • Not addressed: why the renderer reads so slowly during desktop runs. If it gets that far behind, it now reconnects instead of going stale.

Built in Ace

No. Built in Claude Code (lane worktree, isolated loopback host) because the study lead asked that this Mac's Ace Canary stay untouched while a tester drives the desktop-tools study live.

… dropping frames

Why: apps/host/src/gateway.ts#function websocket | gateway sockets must never drop a frame silently; past the backpressure limit they close so the client reconnects and re-watches
@iamnbutler
iamnbutler merged commit 15c496e into main Oct 15, 2026
1 check 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.

Composer keeps showing Stop response after a run finishes

1 participant