mirror of
https://github.com/openai/codex.git
synced 2026-11-05 20:10:33 +00:00
Prewarm code-mode host connections at session startup (#40678)
## What changed - Add the opt-in `code_mode_prewarm` feature to establish the code-mode host session during startup, before the first turn. - Make in-progress host initialization cancellable so a stalled prewarm does not block shutdown. - Share a failed connection attempt with concurrent callers instead of immediately starting another attempt. ## Testing - Verify app-server contacts the configured host before the first turn and can shut down while that connection is stalled. - Exercise shared remote-host behavior with prewarming enabled. GitOrigin-RevId: 3cfde5509be7b4aba80112c36c5616b9a9b632c6
This commit is contained in:
@@ -184,6 +184,8 @@ struct OwnedCodeModeHost {
|
||||
endpoint: HostEndpoint,
|
||||
connection: StdMutex<Option<Arc<Connection>>>,
|
||||
connect_permit: Semaphore,
|
||||
connection_generation: AtomicU64,
|
||||
last_connection_error: StdMutex<Option<(u64, String)>>,
|
||||
next_session_id: AtomicU64,
|
||||
}
|
||||
|
||||
@@ -193,6 +195,8 @@ impl OwnedCodeModeHost {
|
||||
endpoint: HostEndpoint::Process(host_program),
|
||||
connection: StdMutex::new(None),
|
||||
connect_permit: Semaphore::new(/*permits*/ 1),
|
||||
connection_generation: AtomicU64::new(0),
|
||||
last_connection_error: StdMutex::new(None),
|
||||
next_session_id: AtomicU64::new(1),
|
||||
}
|
||||
}
|
||||
@@ -205,6 +209,8 @@ impl OwnedCodeModeHost {
|
||||
},
|
||||
connection: StdMutex::new(None),
|
||||
connect_permit: Semaphore::new(/*permits*/ 1),
|
||||
connection_generation: AtomicU64::new(0),
|
||||
last_connection_error: StdMutex::new(None),
|
||||
next_session_id: AtomicU64::new(1),
|
||||
}
|
||||
}
|
||||
@@ -214,18 +220,42 @@ impl OwnedCodeModeHost {
|
||||
return Ok(connection);
|
||||
}
|
||||
|
||||
let observed_generation = self.connection_generation.load(Ordering::Acquire);
|
||||
let _connect_permit = self.connect_permit.acquire().await.map_err(|_| {
|
||||
ConnectionError::Other("code-mode host connection coordinator closed".into())
|
||||
})?;
|
||||
if let Some(connection) = self.live_connection() {
|
||||
return Ok(connection);
|
||||
}
|
||||
let new_connection = match &self.endpoint {
|
||||
HostEndpoint::Process(host_program) => Connection::spawn(host_program).await?,
|
||||
let completed_generation = self.connection_generation.load(Ordering::Acquire);
|
||||
if completed_generation != observed_generation
|
||||
&& let Some((generation, error)) = self
|
||||
.last_connection_error
|
||||
.lock()
|
||||
.unwrap_or_else(std::sync::PoisonError::into_inner)
|
||||
.as_ref()
|
||||
&& *generation == completed_generation
|
||||
{
|
||||
return Err(ConnectionError::Other(error.clone()));
|
||||
}
|
||||
let connection = match &self.endpoint {
|
||||
HostEndpoint::Process(host_program) => Connection::spawn(host_program).await,
|
||||
HostEndpoint::WebSocket {
|
||||
websocket_url,
|
||||
http_client_factory,
|
||||
} => Connection::connect_websocket(websocket_url, http_client_factory).await?,
|
||||
} => Connection::connect_websocket(websocket_url, http_client_factory).await,
|
||||
};
|
||||
let new_connection = match connection {
|
||||
Ok(connection) => connection,
|
||||
Err(error) => {
|
||||
let generation = self.connection_generation.fetch_add(1, Ordering::AcqRel) + 1;
|
||||
*self
|
||||
.last_connection_error
|
||||
.lock()
|
||||
.unwrap_or_else(std::sync::PoisonError::into_inner) =
|
||||
Some((generation, error.to_string()));
|
||||
return Err(error);
|
||||
}
|
||||
};
|
||||
let new_connection = Arc::new(new_connection);
|
||||
*self
|
||||
|
||||
Reference in New Issue
Block a user