Resolve session storage URL async with timeout

This commit is contained in:
Charles Cunningham
2026-02-16 23:35:16 -08:00
parent 12f7ffdb66
commit 9df71691d2
3 changed files with 47 additions and 22 deletions
+27 -5
View File
@@ -79,6 +79,7 @@ use std::io::ErrorKind;
use std::path::Path;
use std::path::PathBuf;
use std::process::Command;
use std::time::Duration;
#[cfg(test)]
use tempfile::tempdir;
#[cfg(not(target_os = "macos"))]
@@ -110,6 +111,7 @@ pub use codex_git::GhostSnapshotConfig;
/// the context window.
pub(crate) const PROJECT_DOC_MAX_BYTES: usize = 32 * 1024; // 32 KiB
pub(crate) const DEFAULT_AGENT_MAX_THREADS: Option<usize> = Some(6);
const SESSION_OBJECT_STORAGE_URL_CMD_TIMEOUT: Duration = Duration::from_secs(5);
pub const CONFIG_TOML_FILE: &str = "config.toml";
@@ -1904,15 +1906,35 @@ impl Config {
Ok(config)
}
pub fn resolve_session_object_storage_url(&self) -> std::io::Result<Option<String>> {
pub async fn resolve_session_object_storage_url(&self) -> std::io::Result<Option<String>> {
if let Some(url) = self.session_object_storage_url.as_ref() {
return Ok(Some(url.clone()));
}
Self::try_run_command_for_value(
self.session_object_storage_url_cmd.as_deref(),
"session_object_storage_url_cmd",
)
let Some(command) = self.session_object_storage_url_cmd.clone() else {
return Ok(None);
};
let mut handle = tokio::task::spawn_blocking(move || {
Self::try_run_command_for_value(Some(&command), "session_object_storage_url_cmd")
});
let resolved =
match tokio::time::timeout(SESSION_OBJECT_STORAGE_URL_CMD_TIMEOUT, &mut handle).await {
Ok(result) => result.map_err(|err| {
std::io::Error::other(format!("session_object_storage_url_cmd panicked: {err}"))
})?,
Err(_) => {
handle.abort();
return Err(std::io::Error::new(
ErrorKind::TimedOut,
format!(
"session_object_storage_url_cmd timed out after {}s",
SESSION_OBJECT_STORAGE_URL_CMD_TIMEOUT.as_secs()
),
));
}
};
Ok(resolved?)
}
fn load_instructions(codex_dir: Option<&Path>) -> Option<String> {
+19 -16
View File
@@ -3804,22 +3804,6 @@ impl ChatWidget {
// TODO: Enforce email-based access once we have a server-side auth check.
let storage_url = match self.config.resolve_session_object_storage_url() {
Ok(Some(url)) => url,
Ok(None) => {
self.add_error_message(
"Sharing requires `session_object_storage_url` or `session_object_storage_url_cmd` in config.toml."
.to_string(),
);
return;
}
Err(err) => {
self.add_error_message(format!(
"Failed to resolve session object storage URL: {err}"
));
return;
}
};
let owner = self
.auth_manager
.auth_cached()
@@ -3841,8 +3825,27 @@ impl ChatWidget {
self.add_info_message("Sharing current session…".to_string(), None);
let config = self.config.clone();
let app_event_tx = self.app_event_tx.clone();
tokio::spawn(async move {
let storage_url = match config.resolve_session_object_storage_url().await {
Ok(Some(url)) => url,
Ok(None) => {
let cell = history_cell::new_error_event(
"Sharing requires `session_object_storage_url` or `session_object_storage_url_cmd` in config.toml."
.to_string(),
);
app_event_tx.send(AppEvent::InsertHistoryCell(Box::new(cell)));
return;
}
Err(err) => {
let cell = history_cell::new_error_event(format!(
"Failed to resolve session object storage URL: {err}"
));
app_event_tx.send(AppEvent::InsertHistoryCell(Box::new(cell)));
return;
}
};
let result = codex_core::session_share::upload_rollout_with_owner(
&storage_url,
thread_id,
+1 -1
View File
@@ -582,7 +582,7 @@ async fn run_ratatui_app(
match path {
Some(path) => resume_picker::SessionSelection::Fork(path),
None => {
let storage_url = match config.resolve_session_object_storage_url() {
let storage_url = match config.resolve_session_object_storage_url().await {
Ok(Some(url)) => url,
Ok(None) => return missing_session_exit(&mut tui, id_str, "fork"),
Err(err) => {