mirror of
https://github.com/openai/codex.git
synced 2026-11-13 06:45:07 +00:00
Apply refreshed cloud config bundles to later sessions (#37908)
## Why Background refreshes previously warmed only the on-disk cache, so new sessions in the same process continued using the startup snapshot. ## What changed - Make `CloudConfigBundleLoader` retrieve the latest shared bundle on each configuration load. - Update the in-memory bundle after successful refreshes while preserving the last successful bundle when a refresh fails. - Stop refresh work when its loader is replaced or its final clone is dropped. ## Testing - Cover refreshed requirements and managed configuration in later sessions. - Cover concurrent initial loads, refresh failures and recovery, bundle clearing, and refresh-task cancellation. GitOrigin-RevId: ae3d79b575bad71a1eed370cee6dc66dc022ffa8
This commit is contained in:
1 parent
9be95745fb
commit
070a26a1f0
7 files changed
+499
-46
No files matched your search
@@ -1,8 +1,7 @@
|
||||
//! Cloud config bundle lifecycle orchestration.
|
||||
//!
|
||||
//! Startup loads a single shared bundle from cache or backend, and a background
|
||||
//! refresher keeps the cache warm for future app starts without changing the
|
||||
//! already-snapshotted runtime config.
|
||||
//! Startup loads a shared bundle from cache or backend, and background refresh
|
||||
//! updates both the on-disk cache and the bundle observed by future config loads.
|
||||
|
||||
use crate::backend::BundleClient;
|
||||
use crate::backend::BundleRequestError;
|
||||
@@ -27,6 +26,8 @@ use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use std::time::Instant;
|
||||
use tokio::sync::Mutex;
|
||||
use tokio::sync::OnceCell;
|
||||
use tokio::time::sleep;
|
||||
use tokio::time::timeout;
|
||||
|
||||
@@ -77,18 +78,7 @@ pub(crate) struct CloudConfigBundleService<C> {
|
||||
cache: CloudConfigBundleCache,
|
||||
codex_home: AbsolutePathBuf,
|
||||
timeout: Duration,
|
||||
}
|
||||
|
||||
impl<C> Clone for CloudConfigBundleService<C> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
auth_manager: Arc::clone(&self.auth_manager),
|
||||
client: Arc::clone(&self.client),
|
||||
cache: self.cache.clone(),
|
||||
codex_home: self.codex_home.clone(),
|
||||
timeout: self.timeout,
|
||||
}
|
||||
}
|
||||
latest_bundle: OnceCell<Mutex<Result<Option<CloudConfigBundle>, CloudConfigBundleLoadError>>>,
|
||||
}
|
||||
|
||||
impl<C> CloudConfigBundleService<C>
|
||||
@@ -108,9 +98,21 @@ where
|
||||
cache: CloudConfigBundleCache::new(codex_home.clone()),
|
||||
codex_home,
|
||||
timeout,
|
||||
latest_bundle: OnceCell::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) async fn get_latest(
|
||||
&self,
|
||||
) -> Result<Option<CloudConfigBundle>, CloudConfigBundleLoadError> {
|
||||
self.latest_bundle
|
||||
.get_or_init(|| async { Mutex::new(self.load_startup_bundle_with_timeout().await) })
|
||||
.await
|
||||
.lock()
|
||||
.await
|
||||
.clone()
|
||||
}
|
||||
|
||||
pub(crate) async fn load_startup_bundle_with_timeout(
|
||||
&self,
|
||||
) -> Result<Option<CloudConfigBundle>, CloudConfigBundleLoadError> {
|
||||
@@ -482,7 +484,12 @@ where
|
||||
.fetch_remote_bundle_and_update_cache_with_retries(auth, "refresh")
|
||||
.await
|
||||
{
|
||||
Ok(bundle) => emit_load_metric("refresh", "success", bundle.as_ref()),
|
||||
Ok(bundle) => {
|
||||
emit_load_metric("refresh", "success", bundle.as_ref());
|
||||
if let Some(latest_bundle) = self.latest_bundle.get() {
|
||||
*latest_bundle.lock().await = Ok(bundle);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
tracing::error!(
|
||||
path = %self.cache.path().display(),
|
||||
@@ -490,6 +497,12 @@ where
|
||||
"Failed to refresh cloud config bundle cache from remote"
|
||||
);
|
||||
emit_load_metric("refresh", "error", /*bundle*/ None);
|
||||
if let Some(latest_bundle) = self.latest_bundle.get() {
|
||||
let mut latest_bundle = latest_bundle.lock().await;
|
||||
if latest_bundle.is_err() {
|
||||
*latest_bundle = Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
true
|
||||
|
||||
Reference in new issue
Block a user