sqlite: the listen bridge takes the stream bridge's std-thread shape (review 004 item 8) — one dedicated named thread per subscription doing blocking_send, not a spawn_blocking task (past ~500 listeners the blocking-pool ceiling queued the whole engine's seams); spawn failure unsubscribes and fails closed with Error::Database, matching the stream bridge's posture; notify.rs + engine-sqlite.md docs aligned; task -> completed

This commit is contained in:
glm-5.3-flash committed 2026-10-11 10:50:24 +00:00
1 parent 0fadf0f224
commit acdef94058
3 files changed
+67 -12

No files matched your search

+42 -2
View File
@@ -1,7 +1,7 @@
---
id: sqlite-fix-listener-bridge-alignment
name: Align the sqlite listen bridge to the stream bridge's std-thread shape (review 004 item 8)
status: pending
status: completed
depends_on: [sqlite-fix-watcher-death-subscribe]
scope: narrow
risk: low
@@ -53,6 +53,46 @@ stream bridge does.
> To be filled by implementation agent
Decisions of record the description didn't pin:
- The two bridges' shapes are now exactly aligned: a named
`std::thread::Builder` thread (`alkstore-listen-bridge-{channel}`,
mirroring the stream bridge's `alkstore-stream-bridge-{stream}`), the
same loop body, and the stream bridge's spawn-failure posture — a
failed spawn unsubscribes the just-enrolled substrate feed and fails
closed with `Error::Database` (the stream bridge's W-2 no-panic-
across-the-seam shape). The spawn-failure arm is new here
(`spawn_blocking` was infallible at spawn); it matches the stream
bridge rather than being named as a residual difference.
- Docs updated, not code-adjacent only: `notify.rs`'s module docs
(the bridge bullet + the `listen` entry-point doc now pin the
std-thread shape and the spawn-failure arm), and `engine-sqlite.md`'s
notify/listen mapping row (rewritten to the dedicated-thread shape
with the alignment reason). No PROVENANCE row: the register covers
`src/substrate/` only, and this change is engine-level (`notify.rs`).
- No new test: the shape is not contract-observable at the receiver
surface (close semantics, wake delivery, no-replay all unchanged);
the existing pins cover the observable posture, including the
dead-watcher sign from the dependency task
(`listen_after_watcher_death_fails_closed` — green unchanged).
## Summary
> To be filled on completion
> To be filled on completion
`listen()`'s watcher-fanout bridge now runs on a dedicated named
`std::thread` instead of a tokio `spawn_blocking` task per
subscription — the stream bridge's shape, eliminating the blocking-pool
ceiling queueing (review 004 item 8); parked listen bridges no longer
consume the shared blocking pool the engine's seams run on. Spawn
failure fails closed (`Database` + unsubscribe), matching the stream
bridge. Doc alignment: `notify.rs` module + entry-point docs,
`engine-sqlite.md`'s mapping row.
Verified: `cargo build`, `cargo test` (workspace, all green),
`cargo test -p alkstore-sqlite` (201 + 25 tests, green — close
semantics / wake delivery / no-replay pins and the dead-watcher-sign
tests unchanged and passing), fuzz gate
(`cargo test --manifest-path fuzz/shared/Cargo.toml`), clippy
`-D warnings` clean, `cargo fmt --check` clean, rustdoc `-D warnings`
doc gate clean.