Skip to content

fix(codex): keep websocket sessions alive - #4639

Open
lamueno wants to merge 1 commit into
router-for-me:devfrom
lamueno:fix/codex-websocket-heartbeat
Open

fix(codex): keep websocket sessions alive#4639
lamueno wants to merge 1 commit into
router-for-me:devfrom
lamueno:fix/codex-websocket-heartbeat

Conversation

@lamueno

@lamueno lamueno commented Jul 28, 2026

Copy link
Copy Markdown

Summary

  • send a WebSocket Ping control frame every 30 seconds on Codex upstream connections
  • refresh the existing five-minute read deadline whenever a Pong is received
  • stop the per-connection heartbeat on close and invalidate reusable sessions immediately when a Ping write fails

Motivation

Codex upstream WebSocket sessions can be quiet between turns. HTTP/SOCKS relays and other intermediaries may reap those idle connections before CPA's five-minute read deadline. The next request then surfaces a broken pipe, unexpected EOF, or abnormal WebSocket close even though the original upgrade succeeded.

The existing code responds to server Ping frames but does not proactively send Ping frames, and Pong frames do not extend the current read deadline.

Validation

  • go test -race ./internal/runtime/executor -run TestCodexWebsocketHeartbeat -count=3
  • go test ./...
  • go build -o /tmp/cliproxyapi-ws-heartbeat-build ./cmd/server
  • staging A/B through an HTTP proxy, SSH local forward, xray, and VMess outbound:
    • unmodified CPA 7.2.102: the reused upstream connection closed during idle after about 199 seconds with WebSocket 1006 unexpected EOF
    • patched build: the same connection remained reusable after 330 seconds idle and completed a second response; logs showed one upstream connection and a final normal session_closed

No configuration or public API changes are required.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1be39487e8

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

case <-c.done:
return
case <-ticker.C:
errWrite := c.conn.WriteControl(websocket.PingMessage, nil, time.Now().Add(writeTimeout))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Don't let heartbeat pings time out behind data writes

When a request or tool result is being written for longer than 10s, such as a large payload over a slow proxy, this heartbeat WriteControl can wait behind the in-progress data write until the supplied deadline expires; the error path then closes and invalidates an otherwise healthy session. Since the heartbeat is meant to protect idle connections, please skip/serialize pings during application writes or avoid a finite post-connect write deadline so active uploads are not aborted.

AGENTS.md reference: AGENTS.md:L58-L58

Useful? React with 👍 / 👎.

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