mirror of
https://github.com/openai/codex.git
synced 2026-04-24 14:45:27 +00:00
Exit early when session initialization fails (#11908)
Summary - wait for the initial session startup loop to finish and handle exit before waiting for the first message in fresh sessions - propagate AppRunControl::Exit to return immediately when initialization fails
This commit is contained in:
@@ -978,6 +978,27 @@ impl App {
|
||||
self.refresh_status_line();
|
||||
}
|
||||
|
||||
fn should_wait_for_initial_session(session_selection: &SessionSelection) -> bool {
|
||||
matches!(
|
||||
session_selection,
|
||||
SessionSelection::StartFresh | SessionSelection::Exit
|
||||
)
|
||||
}
|
||||
|
||||
fn should_handle_active_thread_events(
|
||||
waiting_for_initial_session_configured: bool,
|
||||
has_active_thread_receiver: bool,
|
||||
) -> bool {
|
||||
has_active_thread_receiver && !waiting_for_initial_session_configured
|
||||
}
|
||||
|
||||
fn should_stop_waiting_for_initial_session(
|
||||
waiting_for_initial_session_configured: bool,
|
||||
primary_thread_id: Option<ThreadId>,
|
||||
) -> bool {
|
||||
waiting_for_initial_session_configured && primary_thread_id.is_some()
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn run(
|
||||
tui: &mut tui::Tui,
|
||||
@@ -1068,6 +1089,8 @@ impl App {
|
||||
let status_line_invalid_items_warned = Arc::new(AtomicBool::new(false));
|
||||
|
||||
let enhanced_keys_supported = tui.enhanced_keys_supported();
|
||||
let wait_for_initial_session_configured =
|
||||
Self::should_wait_for_initial_session(&session_selection);
|
||||
let mut chat_widget = match session_selection {
|
||||
SessionSelection::StartFresh | SessionSelection::Exit => {
|
||||
let init = crate::chatwidget::ChatWidgetInit {
|
||||
@@ -1252,6 +1275,7 @@ impl App {
|
||||
|
||||
let mut thread_created_rx = thread_manager.subscribe_thread_created();
|
||||
let mut listen_for_threads = true;
|
||||
let mut waiting_for_initial_session_configured = wait_for_initial_session_configured;
|
||||
|
||||
let exit_reason = loop {
|
||||
let control = select! {
|
||||
@@ -1264,7 +1288,10 @@ impl App {
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}, if app.active_thread_rx.is_some() => {
|
||||
}, if App::should_handle_active_thread_events(
|
||||
waiting_for_initial_session_configured,
|
||||
app.active_thread_rx.is_some()
|
||||
) => {
|
||||
if let Some(event) = active {
|
||||
app.handle_active_thread_event(tui, event).await?;
|
||||
} else {
|
||||
@@ -1291,6 +1318,12 @@ impl App {
|
||||
AppRunControl::Continue
|
||||
}
|
||||
};
|
||||
if App::should_stop_waiting_for_initial_session(
|
||||
waiting_for_initial_session_configured,
|
||||
app.primary_thread_id,
|
||||
) {
|
||||
waiting_for_initial_session_configured = false;
|
||||
}
|
||||
match control {
|
||||
AppRunControl::Continue => {}
|
||||
AppRunControl::Exit(reason) => break reason,
|
||||
@@ -2915,6 +2948,76 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn startup_waiting_gate_is_only_for_fresh_or_exit_session_selection() {
|
||||
assert_eq!(
|
||||
App::should_wait_for_initial_session(&SessionSelection::StartFresh),
|
||||
true
|
||||
);
|
||||
assert_eq!(
|
||||
App::should_wait_for_initial_session(&SessionSelection::Exit),
|
||||
true
|
||||
);
|
||||
assert_eq!(
|
||||
App::should_wait_for_initial_session(&SessionSelection::Resume(PathBuf::from(
|
||||
"/tmp/restore"
|
||||
))),
|
||||
false
|
||||
);
|
||||
assert_eq!(
|
||||
App::should_wait_for_initial_session(&SessionSelection::Fork(PathBuf::from(
|
||||
"/tmp/fork"
|
||||
))),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn startup_waiting_gate_holds_active_thread_events_until_primary_thread_configured() {
|
||||
let mut wait_for_initial_session =
|
||||
App::should_wait_for_initial_session(&SessionSelection::StartFresh);
|
||||
assert_eq!(wait_for_initial_session, true);
|
||||
assert_eq!(
|
||||
App::should_handle_active_thread_events(wait_for_initial_session, true),
|
||||
false
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
App::should_stop_waiting_for_initial_session(wait_for_initial_session, None),
|
||||
false
|
||||
);
|
||||
if App::should_stop_waiting_for_initial_session(
|
||||
wait_for_initial_session,
|
||||
Some(ThreadId::new()),
|
||||
) {
|
||||
wait_for_initial_session = false;
|
||||
}
|
||||
assert_eq!(wait_for_initial_session, false);
|
||||
|
||||
assert_eq!(
|
||||
App::should_handle_active_thread_events(wait_for_initial_session, true),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn startup_waiting_gate_not_applied_for_resume_or_fork_session_selection() {
|
||||
let wait_for_resume = App::should_wait_for_initial_session(&SessionSelection::Resume(
|
||||
PathBuf::from("/tmp/restore"),
|
||||
));
|
||||
assert_eq!(
|
||||
App::should_handle_active_thread_events(wait_for_resume, true),
|
||||
true
|
||||
);
|
||||
let wait_for_fork = App::should_wait_for_initial_session(&SessionSelection::Fork(
|
||||
PathBuf::from("/tmp/fork"),
|
||||
));
|
||||
assert_eq!(
|
||||
App::should_handle_active_thread_events(wait_for_fork, true),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn enqueue_thread_event_does_not_block_when_channel_full() -> Result<()> {
|
||||
let mut app = make_test_app().await;
|
||||
|
||||
Reference in New Issue
Block a user