mirror of
https://github.com/openai/codex.git
synced 2026-04-24 22:54:54 +00:00
Reapply "Add app-server transport layer with websocket support" with
additional fixes from https://github.com/openai/codex/pull/11313/changes
to avoid deadlocking.
This reverts commit 47356ff83c.
## Summary
To avoid deadlocking when queues are full, we maintain separate tokio
tasks dedicated to incoming vs outgoing event handling
- split the app-server main loop into two tasks in
`run_main_with_transport`
- inbound handling (`transport_event_rx`)
- outbound handling (`outgoing_rx` + `thread_created_rx`)
- separate incoming and outgoing websocket tasks
## Validation
Integration tests, testing thoroughly e2e in codex app w/ >10 concurrent
requests
<img width="1365" height="979" alt="Screenshot 2026-02-10 at 2 54 22 PM"
src="https://github.com/user-attachments/assets/47ca2c13-f322-4e5c-bedd-25859cbdc45f"
/>
---------
Co-authored-by: jif-oai <jif@openai.com>
68 lines
2.2 KiB
Rust
68 lines
2.2 KiB
Rust
use anyhow::Result;
|
|
use codex_core::config::ConfigBuilder;
|
|
use codex_core::config::types::OtelExporterKind;
|
|
use codex_core::config::types::OtelHttpProtocol;
|
|
use pretty_assertions::assert_eq;
|
|
use std::collections::HashMap;
|
|
use tempfile::TempDir;
|
|
|
|
const SERVICE_VERSION: &str = "0.0.0-test";
|
|
|
|
fn set_metrics_exporter(config: &mut codex_core::config::Config) {
|
|
config.otel.metrics_exporter = OtelExporterKind::OtlpHttp {
|
|
endpoint: "http://localhost:4318".to_string(),
|
|
headers: HashMap::new(),
|
|
protocol: OtelHttpProtocol::Json,
|
|
tls: None,
|
|
};
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn app_server_default_analytics_disabled_without_flag() -> Result<()> {
|
|
let codex_home = TempDir::new()?;
|
|
let mut config = ConfigBuilder::default()
|
|
.codex_home(codex_home.path().to_path_buf())
|
|
.build()
|
|
.await?;
|
|
set_metrics_exporter(&mut config);
|
|
config.analytics_enabled = None;
|
|
|
|
let provider = codex_core::otel_init::build_provider(
|
|
&config,
|
|
SERVICE_VERSION,
|
|
Some("codex_app_server"),
|
|
false,
|
|
)
|
|
.map_err(|err| anyhow::anyhow!(err.to_string()))?;
|
|
|
|
// With analytics unset in the config and the default flag is false, metrics are disabled.
|
|
// A provider may still exist for non-metrics telemetry, so check metrics specifically.
|
|
let has_metrics = provider.as_ref().and_then(|otel| otel.metrics()).is_some();
|
|
assert_eq!(has_metrics, false);
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn app_server_default_analytics_enabled_with_flag() -> Result<()> {
|
|
let codex_home = TempDir::new()?;
|
|
let mut config = ConfigBuilder::default()
|
|
.codex_home(codex_home.path().to_path_buf())
|
|
.build()
|
|
.await?;
|
|
set_metrics_exporter(&mut config);
|
|
config.analytics_enabled = None;
|
|
|
|
let provider = codex_core::otel_init::build_provider(
|
|
&config,
|
|
SERVICE_VERSION,
|
|
Some("codex_app_server"),
|
|
true,
|
|
)
|
|
.map_err(|err| anyhow::anyhow!(err.to_string()))?;
|
|
|
|
// With analytics unset in the config and the default flag is true, metrics are enabled.
|
|
let has_metrics = provider.as_ref().and_then(|otel| otel.metrics()).is_some();
|
|
assert_eq!(has_metrics, true);
|
|
Ok(())
|
|
}
|