state: pass state db handles through consumers#20561
Merged
Merged
Conversation
e4a3f2d to
e541ebe
Compare
Contributor
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 830b771d06
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
ad70b50 to
3d5fd73
Compare
owenlin0
approved these changes
May 4, 2026
afd33e8 to
4ee203f
Compare
4ee203f to
3ef0154
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
SQLite state was still being opened from consumer paths, including lazy
OnceCell-backed thread-store call sites. That let one process construct multiple state DB connections for the same Codex home, which makes SQLite lock contention anddatabase is lockedfailures much easier to hit.State DB lifetime should be chosen by main-like entrypoints and tests, then passed through explicitly. Consumers should use the supplied
Option<StateDbHandle>orStateDbHandleand keep their existing filesystem fallback or error behavior when no handle is available.The startup path also needs to keep the rollout crate in charge of SQLite state initialization. Opening
codex_state::StateRuntimedirectly bypasses rollout metadata backfill, so entrypoints should initialize throughcodex_rollout::state_dband receive a handle only after required rollout backfills have completed.What Changed
Option<StateDbHandle>throughThreadManager,LocalThreadStore, app-server processors, TUI app wiring, rollout listing/recording, personality migration, shell snapshot cleanup, session-name lookup, and memory/device-key consumers.codex_rollout::state_db::initthe local state startup path: it opens/migrates SQLite, runs rollout metadata backfill when needed, waits for concurrent backfill workers up to a bounded timeout, verifies completion, and then returns the initialized handle.codex_state::StateRuntime::initto the rollout state initializer so app-server cannot skip rollout backfill._with_state_dbvariants.getConversationSummary(ThreadId)to delegate throughThreadStore::read_threadinstead of a LocalThreadStore-specific rollout path special case.session_meta.idbefore returning them, so a stale SQLite row that points at another thread's JSONL falls back to filesystem search and read-repairs the DB row.debug prompt-inputfilesystem-only so a one-off debug command does not initialize or backfill SQLite state just to print prompt input.Nonewhere filesystem-only behavior is intended.Validation
CARGO_TARGET_DIR=/tmp/codex-target-state-db cargo check -p codex-rollout -p codex-thread-store -p codex-app-server -p codex-core -p codex-tui -p codex-exec -p codex-cli --testsCARGO_TARGET_DIR=/tmp/codex-target-state-db cargo test -p codex-rollout state_db_CARGO_TARGET_DIR=/tmp/codex-target-state-db cargo test -p codex-rollout find_thread_pathCARGO_TARGET_DIR=/tmp/codex-target-state-db cargo test -p codex-rollout find_thread_path -- --nocaptureCARGO_TARGET_DIR=/tmp/codex-target-state-db cargo test -p codex-rollout try_init_ -- --nocaptureCARGO_TARGET_DIR=/tmp/codex-target-state-db cargo test -p codex-rolloutCARGO_TARGET_DIR=/tmp/codex-target-state-db cargo clippy -p codex-rollout --lib -- -D warningsCARGO_TARGET_DIR=/tmp/codex-target-state-db cargo test -p codex-thread-store read_thread_falls_back_when_sqlite_path_points_to_another_thread -- --nocaptureCARGO_TARGET_DIR=/tmp/codex-target-state-db cargo test -p codex-thread-storeCARGO_TARGET_DIR=/tmp/codex-target-state-db cargo test -p codex-core shell_snapshotCARGO_TARGET_DIR=/tmp/codex-target-state-db cargo test -p codex-core --test all personality_migrationCARGO_TARGET_DIR=/tmp/codex-target-state-db cargo test -p codex-core --test all rollout_list_findRUST_MIN_STACK=8388608 CODEX_SKIP_VENDORED_BWRAP=1 CARGO_TARGET_DIR=/tmp/codex-target-state-db cargo test -p codex-core --test all rollout_list_find::find_prefers_sqlite_path_by_id -- --nocaptureRUST_MIN_STACK=8388608 CODEX_SKIP_VENDORED_BWRAP=1 CARGO_TARGET_DIR=/tmp/codex-target-state-db cargo test -p codex-core --test all rollout_list_find -- --nocaptureCARGO_TARGET_DIR=/tmp/codex-target-state-db cargo test -p codex-core interrupt_accounts_active_goal_before_pausingCARGO_TARGET_DIR=/tmp/codex-target-state-db cargo test -p codex-app-server get_auth_status -- --test-threads=1CODEX_SKIP_VENDORED_BWRAP=1 CARGO_TARGET_DIR=/tmp/codex-target-state-db cargo test -p codex-app-server --libCODEX_SKIP_VENDORED_BWRAP=1 CARGO_TARGET_DIR=/tmp/codex-target-state-db cargo check -p codex-rollout -p codex-app-server --testsCARGO_TARGET_DIR=/tmp/codex-target-state-db just fix -p codex-rollout -p codex-thread-store -p codex-core -p codex-app-server -p codex-tui -p codex-exec -p codex-cliCODEX_SKIP_VENDORED_BWRAP=1 CARGO_TARGET_DIR=/tmp/codex-target-state-db just fix -p codex-rollout -p codex-app-serverCARGO_TARGET_DIR=/tmp/codex-target-state-db just fix -p codex-rolloutCODEX_SKIP_VENDORED_BWRAP=1 CARGO_TARGET_DIR=/tmp/codex-target-state-db just fix -p codex-corejust argument-comment-lint -p codex-corejust argument-comment-lint -p codex-rolloutFocused coverage added in
codex-rollout:recorder::tests::state_db_init_backfills_before_returningverifies the rollout metadata row exists before startup init returns.state_db::tests::try_init_waits_for_concurrent_startup_backfillverifies startup waits for another worker to finish backfill instead of disabling the handle for the process.state_db::tests::try_init_times_out_waiting_for_stuck_startup_backfillverifies startup does not hang indefinitely on a stuck backfill lease.tests::find_thread_path_accepts_existing_state_db_path_without_canonical_filenameverifies DB-backed lookup accepts valid existing rollout paths even when the filename does not include the thread UUID.tests::find_thread_path_falls_back_when_db_path_points_to_another_threadverifies DB-backed lookup ignores a stale row whose existing path belongs to another thread and read-repairs the row after filesystem fallback.Focused coverage updated in
codex-core:rollout_list_find::find_prefers_sqlite_path_by_idnow uses a DB-preferred rollout file with matchingsession_meta.id, so it still verifies that valid SQLite paths win without depending on stale/empty rollout contents.cargo test -p codex-app-server thread_list_respects_search_term_filter -- --test-threads=1 --nocapturewas attempted locally but timed out waiting for the app-server test harnessinitializeresponse before reaching the changed thread-list code path.bazel test //codex-rs/thread-store:thread-store-unit-tests --test_output=errorswas attempted locally after the thread-store fix, but this container failed before target analysis while fetchingv8+through BuildBuddy/direct GitHub. The equivalent local crate coverage, includingcargo test -p codex-thread-store, passes.A plain local
cargo check -p codex-rollout -p codex-app-server --testsalso requires systemlibcap.pcforcodex-linux-sandbox; the follow-up app-server check above usedCODEX_SKIP_VENDORED_BWRAP=1in this container.