Skip to content

store: the findings snapshot waits for the write lock instead of failing at once - #975

Merged
svanlabs[bot] merged 1 commit into
mainfrom
fix/scan-snapshot-busy-upgrade
Oct 14, 2026
Merged

svanlabs[bot] merged 1 commit into
mainfrom
fix/scan-snapshot-busy-upgrade

Conversation

@svanlabs

@svanlabs svanlabs Bot commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

Closes #974. Part of #913.

What

Store::record_scan_snapshot began a deferred transaction, read the newest row, then wrote. The first write upgrades a read transaction, and SQLite does not call the busy handler for that upgrade, so it failed at once with database is locked whenever another process held the write lock. The transaction now begins immediate, the same way update_kv (crates/libs/store/src/store/kv.rs:13) already does.

Evidence

  • 11 findings snapshot not recorded: database is locked lines in artifacts/logs/svanbot10.log from 2026-09-28 to 2026-10-14, and no database is locked from any other writer. Two of them are on the installed build 0e3d584, both inside the learner's hourly write burst, with no lock wait reported beside them.
  • New test store::slow::tests::a_read_then_write_waits_for_the_lock_instead_of_failing_at_once: a second connection holds a write transaction for 200 ms. On main the snapshot fails in 0.2 s with Error code 5: database is locked; with the change it waits and is recorded.

Checks

  • scripts/check.sh full green in the worktree: 900 passed, 0 failed, 4 ignored.
  • Store layer only; no decision-path change, so no paired simulation applies.
  • Not changed: compact_rows and the two one-time backfills have the same read-then-write shape but no failure in the log, and compact_rows depends on the failed upgrade on purpose.

Generated-by: claude-code/claude-opus-5-5

🤖 Generated with Claude Code

…ing at once

`record_scan_snapshot` opened a deferred transaction, read the newest
row, then wrote. That first write is an upgrade from a read transaction,
and SQLite calls the busy handler only when the connection holds no
transaction at all, so the upgrade returned `database is locked` without
one retry whenever another process held the write lock. The live log has
11 such failures in 16 days, all from this one writer, two of them on
the installed build 0e3d584 inside the learner's hourly write burst, and
none beside a wait anywhere near the 10 s budget.

The transaction now begins immediate, as `update_kv` already does, so
the lock is taken by a statement the busy handler covers. The test holds
a write transaction on a second connection for 200 ms and expects the
snapshot to wait and be recorded; before the change it failed in 0.2 s
with the error from the log.

Closes #974.

Generated-by: claude-code/claude-opus-5-5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@svanlabs
svanlabs Bot enabled auto-merge October 14, 2026 04:42
@svanlabs
svanlabs Bot merged commit 9a46bc6 into main Oct 14, 2026
3 checks passed
@svanlabs
svanlabs Bot deleted the fix/scan-snapshot-busy-upgrade branch October 14, 2026 04:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fix: the findings snapshot fails at once with database is locked instead of waiting for the write lock

0 participants