From 7f7c7c2c07a107668d6477fcab8d916848711b71 Mon Sep 17 00:00:00 2001 From: Dylan Hurd Date: Tue, 28 Apr 2026 12:08:41 -0700 Subject: [PATCH] Fix log db batch flush flake (#19959) ## Why The log DB writer batches tracing events before inserting them into SQLite, but `tokio::time::interval` produces an immediate first tick. That meant the inserter could flush the first accepted log entry before `batch_size` was reached, making `configured_batch_size_flushes_without_explicit_flush` timing-sensitive in CI. ## What Changed - Consume the interval's startup tick before entering the inserter loop, so interval flushing starts after the configured delay. - Remove the test's startup sleep, which was masking the race instead of proving the batch-size behavior. ## Validation - `cargo test -p codex-state` - `cargo test -p codex-state configured_batch_size_flushes_without_explicit_flush` passed 3 consecutive focused runs - PR checks passed across `rust-ci`, Bazel, `ci`, `sdk`, `cargo-deny`, Codespell, blob-size policy, and CLA --- codex-rs/state/src/log_db.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/codex-rs/state/src/log_db.rs b/codex-rs/state/src/log_db.rs index a9da47532..6024d6bda 100644 --- a/codex-rs/state/src/log_db.rs +++ b/codex-rs/state/src/log_db.rs @@ -367,6 +367,8 @@ async fn run_inserter( ) { let mut buffer = Vec::with_capacity(config.batch_size); let mut ticker = tokio::time::interval(config.flush_interval); + // Consume the immediate startup tick so entries flush after the interval. + ticker.tick().await; loop { tokio::select! { maybe_command = receiver.recv() => { @@ -645,7 +647,6 @@ mod tests { flush_interval: std::time::Duration::from_secs(60), }, ); - tokio::time::sleep(std::time::Duration::from_millis(10)).await; let guard = tracing_subscriber::registry() .with(