mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
f886e33e5a
## Why Remote environments registered through `environment/add` currently use the fixed 10-second WebSocket connection timeout. Slow-starting executors need a caller-selected connection window, but this should not add retry policy or couple exec-server behavior to Core’s `deferred_executor` feature. Make the timeout an optional part of the existing experimental request. Existing clients continue using the current default, while callers that know an executor may take longer can request a larger window explicitly. Depends on #28683. ## What changed - Add optional `connectTimeoutMs` to `EnvironmentAddParams` and document it in the app-server README. - Pass the optional timeout through `EnvironmentRequestProcessor` into one `EnvironmentManager::upsert_environment()` path; the manager applies the existing default when it is omitted. - Preserve the existing single-attempt lifecycle. The configured value controls WebSocket connection and handshake time for both initial connection and later reconnects; initialization retains its separate timeout. - Add an app-server integration test that sends the real JSON-RPC request and verifies a stalled handshake observes the requested timeout. ## Test plan - `just test -p codex-app-server-protocol` - `just test -p codex-exec-server` - `just test -p codex-app-server environment_add_applies_connect_timeout` ## Rollout This is additive and does not enable `deferred_executor`. Callers should send a non-default timeout only after a compatible app-server is deployed; omitted or `null` values retain the existing 10-second default.
53 lines
1.8 KiB
Rust
53 lines
1.8 KiB
Rust
use std::time::Duration;
|
|
|
|
use anyhow::Result;
|
|
use app_test_support::TestAppServer;
|
|
use app_test_support::to_response;
|
|
use codex_app_server_protocol::EnvironmentAddResponse;
|
|
use codex_app_server_protocol::JSONRPCResponse;
|
|
use codex_app_server_protocol::RequestId;
|
|
use serde_json::json;
|
|
use tempfile::TempDir;
|
|
use tokio::io::AsyncReadExt;
|
|
use tokio::net::TcpListener;
|
|
use tokio::time::timeout;
|
|
|
|
const RPC_TIMEOUT: Duration = Duration::from_secs(10);
|
|
const CONNECTION_CLOSE_TIMEOUT: Duration = Duration::from_secs(5);
|
|
|
|
#[tokio::test]
|
|
async fn environment_add_applies_connect_timeout() -> Result<()> {
|
|
let listener = TcpListener::bind("127.0.0.1:0").await?;
|
|
let exec_server_url = format!("ws://{}", listener.local_addr()?);
|
|
let stalled_server = tokio::spawn(async move {
|
|
let (mut socket, _) = listener.accept().await?;
|
|
let mut request = Vec::new();
|
|
socket.read_to_end(&mut request).await?;
|
|
anyhow::ensure!(!request.is_empty(), "expected a WebSocket handshake");
|
|
Ok::<_, anyhow::Error>(())
|
|
});
|
|
let codex_home = TempDir::new()?;
|
|
let mut app_server = TestAppServer::new(codex_home.path()).await?;
|
|
timeout(RPC_TIMEOUT, app_server.initialize()).await??;
|
|
|
|
let request_id = app_server
|
|
.send_raw_request(
|
|
"environment/add",
|
|
Some(json!({
|
|
"environmentId": "remote-a",
|
|
"execServerUrl": exec_server_url,
|
|
"connectTimeoutMs": 1_000,
|
|
})),
|
|
)
|
|
.await?;
|
|
let response: JSONRPCResponse = timeout(
|
|
RPC_TIMEOUT,
|
|
app_server.read_stream_until_response_message(RequestId::Integer(request_id)),
|
|
)
|
|
.await??;
|
|
let _: EnvironmentAddResponse = to_response(response)?;
|
|
|
|
timeout(CONNECTION_CLOSE_TIMEOUT, stalled_server).await???;
|
|
Ok(())
|
|
}
|