Files
codex/codex-rs/network-proxy/src/connection_lifecycle/scope.rs
T
jelson-oai 5a65fd87d8 Close active network proxy connections on teardown (#43884)
## Why

Stopping proxy listeners could leave accepted connections and half-closed tunnels alive after their owning thread was unloaded.

## What changed

Tie HTTP and SOCKS5 connection work, including HTTP CONNECT upgrades, to the lifetime of the proxy listeners. Cancel connections across the main and environment proxies when the handle is dropped, shutdown is requested, or `wait()` is canceled. Explicit shutdown waits for connection cleanup.

## Testing

Add live TCP regression tests for HTTP keep-alive connections and open or half-closed HTTP CONNECT and SOCKS5 tunnels across shutdown, handle drop, and canceled waits. Verify that half-closed tunnels still carry return traffic while the proxy is running, and that repeated thread creation and unloading closes managed proxy tunnels.

GitOrigin-RevId: b523f3b08d73e9ae368f6932952cc930c7b038c9
2026-09-08 18:40:17 +00:00

36 lines
984 B
Rust

//! Owns cancellation and completion of a proxy's accepted connections and descendant tasks.
use rama_core::graceful::Shutdown;
use rama_core::graceful::ShutdownGuard;
use tokio::sync::oneshot;
pub(crate) struct ConnectionLifecycle {
// Only the runtime owner holds the sender. Dropping it also signals shutdown when an
// enclosing wait/shutdown future is cancelled, without spawning another cleanup task.
cancel: Option<oneshot::Sender<()>>,
shutdown: Shutdown,
}
impl ConnectionLifecycle {
pub(crate) fn new() -> Self {
let (cancel, signal) = oneshot::channel();
Self {
cancel: Some(cancel),
shutdown: Shutdown::new(signal),
}
}
pub(crate) fn guard(&self) -> ShutdownGuard {
self.shutdown.guard()
}
pub(crate) fn cancel(&mut self) {
self.cancel.take();
}
pub(crate) async fn shutdown(mut self) {
self.cancel();
self.shutdown.shutdown().await;
}
}