- explicit `PRAGMA busy_timeout = 5000` in the open pragma block, pinned constant, not a knob: DQ-7's co-tenancy evidence shows no contention observable at POC scale, so there is no tuning story; the value matches the family contract (alkstore-sqlite pins the same 5000 ms) so the first consumer's co-tenant assembly over one sqlite file has a visible contention posture, not a rusqlite- default coincidence - module doc carries the contention posture alongside the durability posture; the constructor doc records the choice and its reason - pragma posture test extended: busy_timeout asserted 5000 on the backend's own connection - fuzz/Cargo.lock: alkcall 0.10.0 resolution drift from the dep bump, refreshed by the corpus-replay gate run Verification: cargo test (default: 149+54+4+2 passed); clippy --all-targets -- -D warnings (default + all-features); cargo fmt --check; cargo test --manifest-path fuzz/shared/Cargo.toml
4.3 KiB
id, name, status, depends_on, scope, risk, impact, level, tags
| id | name | status | depends_on | scope | risk | impact | level | tags | |||
|---|---|---|---|---|---|---|---|---|---|---|---|
| c3-sqlite-busy-timeout | C-3 — sqlite busy_timeout explicit: knob or pinned constant, the contention posture contracted | completed | single | trivial | component | implementation |
|
Description
Review-002 C-3 (ride-along). The sqlite engine sets its durability
posture explicitly — PRAGMA journal_mode = WAL +
PRAGMA synchronous = NORMAL (src/sqlite.rs:156-163, WAL engagement
verified at open) — but sets no busy_timeout: contention
behavior rides rusqlite's implicit 5-second default, which happens to
equal alkstore's explicit 5000 ms. The first consumer's deployment
shape is a co-tenant assembly on one sqlite file (alkstore machinery +
alkblobs kv + consumer-own tables), where this store's writers
serialize behind every other co-tenant writer — the
durability/contention posture is load-bearing there and should be a
visible contract, not a library-default coincident.
Land an explicit busy_timeout:
- The shape is the task's design point (re-derive; the review offers either): a knob on the engine options alongside the durability posture (the constructor-tunable pattern), or a pinned constant set at open (the ADR-015-style no-knob posture). The co-tenancy evidence (DQ-7: no contention observable at POC scale) argues the value is not performance-tuned yet — a pinned constant matching the family's 5000 ms is the lean default; a knob is justified only if the session finds the co-tenant story wants it. Record the choice and its reason.
- The pragma set at open next to the durability block; if a pragma's engagement is verifiable (as journal_mode's is), verify it the same way.
- The module doc line: the contention posture joins the durability posture as stated contract.
Acceptance Criteria
busy_timeoutset explicitly at open (the knob/constant choice recorded with its reason)- The module doc carries the contention posture alongside the durability posture
- A server-less test asserts the posture (the pragma observable or the knob's effect) — green in the default build
- Gates green:
cargo test(default), clippy--all-targets -- -D warnings,cargo fmt --check
References
- docs/reviews/002-first-consumer-review.md (C-3)
- src/sqlite.rs:156-163 (the durability pragma block — the new pragma's home)
- /workspace/@alkdev/alkgit/docs/research/substrate-recomposition.md (upstream-ask 4; DQ-7's co-tenancy measurement)
- alkstore's sqlite engine (the explicit 5000 ms — the family contrast)
Notes
Chosen shape: pinned constant set at open (the ADR-015-style no-knob posture). Reason: the co-tenancy evidence (DQ-7, recorded in the substrate-recomposition doc) is that no contention is observable at POC scale — there is no tuning story to hang a knob on, so a tunable surface would be speculative API. The value pinned is 5000 ms, matching the family contrast (alkstore-sqlite pins
PRAGMA busy_timeout = 5000explicitly insubstrate/schema.rs::Default_PRAGMAS): the first consumer's co-tenant assembly over one sqlite file now has a visible contract aligned with the alkstore machinery it co-tenants with, rather than riding rusqlite's implicit 5 s default by coincidence.Implementation (src/sqlite.rs):
PRAGMA busy_timeout = 5000;joins the durability block inSqliteBackend::new'sexecute_batch(verified live viaPRAGMA busy_timeout; no separate result check needed — the setting cannot silently fail the way WAL can).- The module doc's opening line now states the contention posture alongside the durability posture, with the pinned-constant reason recorded there.
- The constructor doc comment carries the choice and its reason.
Summary
Landed: explicit
busy_timeout = 5000at open as a pinned constant (src/sqlite.rs), the module doc carrying the contention posture as stated contract, and the pragma posture test extended to assertbusy_timeout == 5000on the backend's own connection (opens_with_wal_synchronous_normal_and_busy_timeout). All gates green:cargo test(default: 149+54+4+2 passed), clippy--all-targets -- -D warnings(default and all-features),cargo fmt --check, and the fuzz corpus-replay gate (fuzz/shared).