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:
Vivian Fang authored and copyberry committed 2026-08-25 19:16:45 +00:00
1 parent 17c4c47dfa
commit 4b24638e1c
6 files changed
+105 -14

No files matched your search

+16 -11
View File
@@ -72,7 +72,7 @@ pub(crate) struct CodeModeService {
availability: Result<(), String>,
dispatch_broker: Arc<CodeModeDispatchBroker>,
default_exec_yield_time_ms: u64,
shutting_down: AtomicBool,
shutdown_token: CancellationToken,
unavailable_warning_emitted: AtomicBool,
}
@@ -89,7 +89,7 @@ impl CodeModeService {
availability,
dispatch_broker,
default_exec_yield_time_ms: config.default_exec_yield_time_ms,
shutting_down: AtomicBool::new(false),
shutdown_token: CancellationToken::new(),
unavailable_warning_emitted: AtomicBool::new(false),
}
}
@@ -160,7 +160,7 @@ impl CodeModeService {
}
pub(crate) async fn shutdown(&self) -> Result<(), String> {
self.shutting_down.store(true, Ordering::Release);
self.shutdown_token.cancel();
// Join any initialization already in progress without initializing an unused service.
match self
.session
@@ -206,20 +206,25 @@ impl CodeModeService {
)
}
async fn session(&self) -> Result<Arc<dyn CodeModeSession>, String> {
if self.shutting_down.load(Ordering::Acquire) {
pub(crate) async fn session(&self) -> Result<Arc<dyn CodeModeSession>, String> {
if self.shutdown_token.is_cancelled() {
return Err("code mode session is shutting down".to_string());
}
self.session
.get_or_try_init(|| async {
if self.shutting_down.load(Ordering::Acquire) {
if self.shutdown_token.is_cancelled() {
return Err("code mode session is shutting down".to_string());
}
let session = self
.session_provider
.create_session(self.dispatch_broker.clone())
.await?;
if self.shutting_down.load(Ordering::Acquire) {
let session = tokio::select! {
biased;
_ = self.shutdown_token.cancelled() => {
return Err("code mode session is shutting down".to_string());
}
session = self
.session_provider
.create_session(self.dispatch_broker.clone()) => session?,
};
if self.shutdown_token.is_cancelled() {
let _ = session.shutdown().await;
return Err("code mode session is shutting down".to_string());
}