fix(proxy): keep terminal WS open on idle by clearing upstream read timeout#99
Closed
viniciussouzax wants to merge 1 commit into
Closed
Conversation
…imeout websocket-client's create_connection(timeout=10) also sets the socket read timeout, and it persists after connect. As a result upstream.recv() in the _pump_upstream_to_client thread raised a timeout every 10s on an idle chat and tore down the /terminal/ws bridge. The frontend then reconnected on a ~10s loop, visible as the chat flashing "connecting" (and "Invalid frame header" in the browser console). Clear the read timeout after connect (upstream.settimeout(None)) so recv() blocks until real data arrives or the socket closes. Genuine disconnects are still detected by the client receive loop (its own 30s timeout) and the frontend ping/pong heartbeat. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Sorry @viniciussouzax, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On a deployment where the browser reaches the chat through the Flask
/terminal/wsproxy (public VPS, Cloudflare/Tailscale tunnel, reverse proxy),an idle chat reconnects on a ~10s loop. The user sees the chat flashing
"connecting", and the browser console logs repeated:
Server logs confirm a fresh
GET /terminal/wsevery ~10s while the tab is open and idle.Root cause
In
register_websocket_proxy, the upstream socket is opened with:websocket-client'stimeoutargument is not only a connect timeout: italso becomes the socket read timeout and persists for the life of the
connection. So
upstream.recv()in the_pump_upstream_to_clientthreadraises a timeout after 10s with no upstream data, the pump exits,
stopisset, and the client socket is closed. The frontend then reconnects (its ping
is every 25s, so the bridge dies before each cycle).
Fix
Clear the read timeout right after connect so
recv()blocks until real dataarrives or the socket closes:
Genuine disconnects are still detected by the client receive loop (its own
30s
client_ws.receive(timeout=30)) and the frontend ping/pong heartbeat, sono half-open sockets are introduced.
Testing
docker logsshowsGET /terminal/wsevery~10s; UI flashes "connecting"; console shows "Invalid frame header".
window; no console errors. Streaming responses and the terminal are unaffected.
Related
Complementary to #86, which fixes the client-side idle teardown
(
client_ws.receivereturningNone→break). This PR fixes theupstream-side read timeout. The two are independent; both are needed for a
fully idle-stable bridge.