From 72f757d1447cbff718eb8d213ecff12f9e759578 Mon Sep 17 00:00:00 2001 From: Eric Traut Date: Thu, 23 Apr 2026 18:47:28 -0700 Subject: [PATCH] Increase app-server WebSocket outbound buffer (#19246) Fixes #18203. ## Why Remote TUI clients connected through `codex app-server --listen ws://...` can receive short bursts of outbound turn and tool-output notifications. The WebSocket transport previously used the shared 128-message channel capacity for its outbound writer queue, so a healthy client that briefly lagged during normal output streaming could fill the queue and be disconnected immediately. This is a smaller mitigation than #18265: instead of adding a new overflow/backpressure pipeline, keep the existing non-blocking router behavior and give WebSocket clients enough bounded headroom for realistic bursts. ## What Changed - Added a WebSocket-only outbound writer capacity of `64 * 1024` messages. - Used that larger capacity only for the WebSocket data writer queue in `codex-rs/app-server/src/transport/websocket.rs`. - Left the shared `CHANNEL_CAPACITY` and the existing disconnect-on-full behavior unchanged for internal/control channels and genuinely stuck clients. ## Verification - `cargo test -p codex-app-server transport::tests::broadcast_does_not_block_on_slow_connection` - Manually retried the #18203 repro prompt against the remote TUI and confirmed it stayed connected. --- codex-rs/app-server/src/transport/websocket.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/codex-rs/app-server/src/transport/websocket.rs b/codex-rs/app-server/src/transport/websocket.rs index 1840231c3..783018946 100644 --- a/codex-rs/app-server/src/transport/websocket.rs +++ b/codex-rs/app-server/src/transport/websocket.rs @@ -43,6 +43,11 @@ use tracing::error; use tracing::info; use tracing::warn; +/// WebSocket clients can briefly lag behind normal turn output bursts while the +/// writer task is healthy, so give them more headroom than internal channels. +const WEBSOCKET_OUTBOUND_CHANNEL_CAPACITY: usize = 32 * 1024; +const _: () = assert!(WEBSOCKET_OUTBOUND_CHANNEL_CAPACITY > CHANNEL_CAPACITY); + fn colorize(text: &str, style: Style) -> String { text.if_supports_color(Stream::Stderr, |value| value.style(style)) .to_string() @@ -174,7 +179,8 @@ pub(crate) async fn run_websocket_connection( StreamError: std::fmt::Display + Send + 'static, { let connection_id = next_connection_id(); - let (writer_tx, writer_rx) = mpsc::channel::(CHANNEL_CAPACITY); + let (writer_tx, writer_rx) = + mpsc::channel::(WEBSOCKET_OUTBOUND_CHANNEL_CAPACITY); let writer_tx_for_reader = writer_tx.clone(); let disconnect_token = CancellationToken::new(); if transport_event_tx