aw-sync/tests/sync_roundtrip.rs::test_own_data_does_not_return_via_peer (added in #648) fails on Windows in the activitywatch bundle CI, and today it went from occasionally-flaky to reliably failing (2/2 runs, each already wrapped in a retry action):
thread '<unnamed>' panicked at aw-datastore\src\worker.rs:155:14:
Failed to query journal_mode: SqliteFailure(Error { code: DatabaseBusy, extended_code: 5 }, Some("database is locked"))
thread 'test_own_data_does_not_return_via_peer' panicked at aw-sync\tests\sync_roundtrip.rs:72:10:
called `Result::unwrap()` on an `Err` value: InternalError("Failed to receive response, datastore worker died while handling request: RecvError")
Evidence it's environmental timing rather than a code regression: the bundle pin (b2e2dee) is unchanged since 2026-08-20, the same job passed on 2026-08-27, and this repo's own Windows CI was green at #648 merge time and on recent master. Something in the runner environment shifted the timing enough to make the race land consistently.
Two candidate mechanisms, both worth fixing:
-
tmp filename collisions across parallel tests. tmp_db() builds uniqueness from process::id() + name + SystemTime nanos. Cargo runs the tests in the same process on parallel threads, and each test uses the same name values (a-local, a-export, ...). If two tests hit the same clock tick, they open the same db file from two datastore workers; the second journal_mode=WAL pragma needs an exclusive lock and dies with SQLITE_BUSY. Fix: add a per-call AtomicUsize counter to the filename (or use tempfile).
-
No busy_timeout on any connection. git grep busy_timeout comes up empty. The WAL pragma at worker.rs:155 runs with rusqlite's default (no busy handler), so any transient holder of the file — including Windows Defender scanning a freshly created file, a well-known Windows CI failure mode — is an instant panic rather than a short wait. Setting conn.busy_timeout(Duration::from_secs(5)) before the pragmas makes open robust. This is also production-relevant: any tool opening a datastore file that briefly overlaps with another handle (e.g. aw-sync touching an export while a checkpoint runs) currently panics the worker instead of waiting.
Suggest doing both: (1) fixes the test correctness, (2) fixes the class of failure.
Context: found while chasing red master CI on ActivityWatch/activitywatch (run 33269017968, Windows Qt job, both attempts).
aw-sync/tests/sync_roundtrip.rs::test_own_data_does_not_return_via_peer(added in #648) fails on Windows in the activitywatch bundle CI, and today it went from occasionally-flaky to reliably failing (2/2 runs, each already wrapped in a retry action):Evidence it's environmental timing rather than a code regression: the bundle pin (b2e2dee) is unchanged since 2026-08-20, the same job passed on 2026-08-27, and this repo's own Windows CI was green at #648 merge time and on recent master. Something in the runner environment shifted the timing enough to make the race land consistently.
Two candidate mechanisms, both worth fixing:
tmp filename collisions across parallel tests.
tmp_db()builds uniqueness fromprocess::id() + name + SystemTime nanos. Cargo runs the tests in the same process on parallel threads, and each test uses the samenamevalues (a-local,a-export, ...). If two tests hit the same clock tick, they open the same db file from two datastore workers; the secondjournal_mode=WALpragma needs an exclusive lock and dies withSQLITE_BUSY. Fix: add a per-callAtomicUsizecounter to the filename (or usetempfile).No
busy_timeouton any connection.git grep busy_timeoutcomes up empty. The WAL pragma atworker.rs:155runs with rusqlite's default (no busy handler), so any transient holder of the file — including Windows Defender scanning a freshly created file, a well-known Windows CI failure mode — is an instant panic rather than a short wait. Settingconn.busy_timeout(Duration::from_secs(5))before the pragmas makes open robust. This is also production-relevant: any tool opening a datastore file that briefly overlaps with another handle (e.g. aw-sync touching an export while a checkpoint runs) currently panics the worker instead of waiting.Suggest doing both: (1) fixes the test correctness, (2) fixes the class of failure.
Context: found while chasing red master CI on ActivityWatch/activitywatch (run 33269017968, Windows Qt job, both attempts).