diff --git a/codex-rs/cli/tests/exec_server.rs b/codex-rs/cli/tests/exec_server.rs index 001a69e619..36c16bb565 100644 --- a/codex-rs/cli/tests/exec_server.rs +++ b/codex-rs/cli/tests/exec_server.rs @@ -267,7 +267,7 @@ metrics_exporter = {{ otlp-http = {{ endpoint = "{collector_url}/v1/metrics", pr prepend_path_dirs: environment_info.prepend_path_dirs.clone(), ..EnvironmentInfo::local() }; - assert_eq!(environment_info, expected_info); + assert_eq!(environment_info.as_ref(), &expected_info); std::fs::remove_file(&manifest)?; assert_eq!(client.force_environment_info().await?, expected_info); diff --git a/codex-rs/exec-server/src/client.rs b/codex-rs/exec-server/src/client.rs index 1192a5b8f3..94195c73b3 100644 --- a/codex-rs/exec-server/src/client.rs +++ b/codex-rs/exec-server/src/client.rs @@ -290,7 +290,7 @@ struct Inner { session_id: OnceLock, retired: CancellationToken, /// Caches metadata from initialization or the first successful info request for this client's lifetime. - environment_info: OnceCell, + environment_info: OnceCell>, reconnect_strategy: Option, } @@ -652,7 +652,7 @@ impl HttpClient for LazyRemoteExecServerClient { impl LazyRemoteExecServerClient { pub(crate) async fn environment_info(&self) -> Result { - self.get().await?.environment_info().await + Ok(self.get().await?.environment_info().await?.as_ref().clone()) } } @@ -827,11 +827,11 @@ impl ExecServerClient { self.call(EXEC_METHOD, ¶ms).await } - /// Returns cached executor metadata, fetching it lazily if initialization omitted it. - pub async fn environment_info(&self) -> Result { + /// Returns shared cached executor metadata, fetching it lazily if initialization omitted it. + pub async fn environment_info(&self) -> Result, ExecServerError> { self.inner .environment_info - .get_or_try_init(|| self.force_environment_info()) + .get_or_try_init(|| async { self.force_environment_info().await.map(Arc::new) }) .await .cloned() } @@ -1292,7 +1292,7 @@ impl ExecServerClient { .await?; if let Some(info) = initialize_response.environment_info { assert!( - client.inner.environment_info.set(info).is_ok(), + client.inner.environment_info.set(Arc::new(info)).is_ok(), "new client metadata cache must be empty" ); } @@ -2668,10 +2668,13 @@ mod tests { }) .await?; - assert_eq!(client.environment_info().await?, expected_info); + let info = client.environment_info().await?; + assert_eq!(info.as_ref(), &expected_info); server.await?; // The server is gone, so a cloned client must use the shared cache. - assert_eq!(client.clone().environment_info().await?, expected_info); + let cached_info = client.clone().environment_info().await?; + assert_eq!(cached_info.as_ref(), &expected_info); + assert!(Arc::ptr_eq(&info, &cached_info)); Ok(()) }