mirror of
https://github.com/openai/codex.git
synced 2026-05-02 04:11:39 +03:00
fix(app-server): emit turn/started only when turn actually starts (#13261)
This is a follow-up for https://github.com/openai/codex/pull/13047 ## Why We had a race where `turn/started` could be observed before the thread had actually transitioned to `Active`. This was because we eagerly emitted `turn/started` in the request handler for `turn/start` (and `review/start`). That was showing up as flaky `thread/resume` tests, but the real issue was broader: a client could see `turn/started` and still get back an idle thread immediately afterward. The first idea was to eagerly call `thread_watch_manager.note_turn_started(...)` from the `turn/start` request path. That turns out to be unsafe, because `submit(Op::UserInput)` only queues work. If a turn starts and completes quickly, request-path bookkeeping can race with the real lifecycle events and leave stale running state behind. **The real fix** is to move `turn/started` to emit only after the turn _actually_ starts, so we do that by waiting for the `EventMsg::TurnStarted` notification emitted by codex core. We do this for both `turn/start` and `review/start`. I also verified this change is safe for our first-party codex apps - they don't have any assumptions that `turn/started` is emitted before the RPC response to `turn/start` (which is correct anyway). I also removed `single_client_mode` since it isn't really necessary now. ## Testing - `cargo test -p codex-app-server thread_resume -- --nocapture` - `cargo test -p codex-app-server 'suite::v2::turn_start::turn_start_emits_notifications_and_accepts_model_override' -- --exact --nocapture` - `cargo test -p codex-app-server`
This commit is contained in:
@@ -150,7 +150,6 @@ pub(crate) struct MessageProcessorArgs {
|
||||
pub(crate) outgoing: Arc<OutgoingMessageSender>,
|
||||
pub(crate) arg0_paths: Arg0DispatchPaths,
|
||||
pub(crate) config: Arc<Config>,
|
||||
pub(crate) single_client_mode: bool,
|
||||
pub(crate) cli_overrides: Vec<(String, TomlValue)>,
|
||||
pub(crate) loader_overrides: LoaderOverrides,
|
||||
pub(crate) cloud_requirements: CloudRequirementsLoader,
|
||||
@@ -166,7 +165,6 @@ impl MessageProcessor {
|
||||
outgoing,
|
||||
arg0_paths,
|
||||
config,
|
||||
single_client_mode,
|
||||
cli_overrides,
|
||||
loader_overrides,
|
||||
cloud_requirements,
|
||||
@@ -202,7 +200,6 @@ impl MessageProcessor {
|
||||
config: Arc::clone(&config),
|
||||
cli_overrides: cli_overrides.clone(),
|
||||
cloud_requirements: cloud_requirements.clone(),
|
||||
single_client_mode,
|
||||
feedback,
|
||||
});
|
||||
let config_api = ConfigApi::new(
|
||||
|
||||
Reference in New Issue
Block a user