SQLite concurrency: cache=shared, no busy_timeout, no WAL, unbounded pool — concurrent writers get SQLITE_BUSY, deliveries stick pending #304

Closed
opened 2026-08-30 03:57:12 +02:00 by clawbot · 1 comment
Collaborator

From audit #303 (unfit for purpose).

SQLite opened with cache=shared, no busy_timeout, no WAL, unbounded database/sql pool (internal/database/database.go:140, internal/database/webhook_db_manager.go:237). The ingest handler's write transaction (internal/handlers/webhook.go:223) races engine workers writing results/status to the same per-webhook file (internal/delivery/engine.go:761, :778): under any concurrency, senders get 500s from SQLITE_BUSY/SQLITE_LOCKED and deliveries stick pending (write errors only logged). No test exercises concurrent writers.

Done: WAL + busy_timeout (or serialized writes), bounded pool, no cache=shared; a test with concurrent ingest + engine writers passes; failed status writes are not silently logged away.

From audit #303 (unfit for purpose). SQLite opened with `cache=shared`, no `busy_timeout`, no WAL, unbounded `database/sql` pool (`internal/database/database.go:140`, `internal/database/webhook_db_manager.go:237`). The ingest handler's write transaction (`internal/handlers/webhook.go:223`) races engine workers writing results/status to the same per-webhook file (`internal/delivery/engine.go:761`, `:778`): under any concurrency, senders get 500s from `SQLITE_BUSY`/`SQLITE_LOCKED` and deliveries stick `pending` (write errors only logged). No test exercises concurrent writers. Done: WAL + `busy_timeout` (or serialized writes), bounded pool, no `cache=shared`; a test with concurrent ingest + engine writers passes; failed status writes are not silently logged away.
Author
Collaborator

Audit #303 read main. PR #111's next already landed this via #256 (WAL, busy timeout, _txlock=immediate, no cache=shared, bounded pool, verified under concurrent load). Closes on merge of #111; other #303-derived issues (#305-#310) should be re-checked against next before dispatch.

Audit #303 read `main`. PR #111's `next` already landed this via #256 (WAL, busy timeout, `_txlock=immediate`, no `cache=shared`, bounded pool, verified under concurrent load). Closes on merge of #111; other #303-derived issues (#305-#310) should be re-checked against `next` before dispatch.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/webhooker#304