sqlite: panic-safety armor for the auto-commit seams (review 004 item 1)

with_writer/with_reader/blocking_read release their slot/pool
connection only on the normal return — a panic inside the closure
wedged the single writer slot forever (Writer::acquire waits on a
condvar) and permanently shrank the reader pool (outstanding never
decremented on abandonment). The seams now ride RAII drop-guards
(ConnLease's idiom): the normal arm defuses and releases unchanged;
the unwind arm drops the unknown-state connection and takes the
established abandonment dispositions — Writer::replenish() (the tick's
poisoned arm as a substrate method, the writer now holding its path)
and Readers::abandon() (outstanding decrement + pool-locked notify).
Three panic-injection tests pin the properties; no reachable panic
path exists in production — this is the defense-in-depth armor the
review scoped. Task: sqlite-fix-seam-panic-safety.
This commit is contained in:
glm-5.3-flash committed 2026-10-11 09:55:45 +00:00
1 parent 9bbe645558
commit 22f25ffafd
5 files changed
+403 -16

No files matched your search

+3 -1
View File
@@ -143,7 +143,7 @@ pub(crate) fn open_store(path: &str, opts: SqliteOpts) -> alkstore::Result<Sqlit
.map_err(|e| database_error(format!("failed to spawn update watcher: {e}")))?;
Ok(SqliteStore {
writer: Arc::new(Writer::new(writer_conn)),
writer: Arc::new(Writer::new(path.to_string(), writer_conn)),
readers: Arc::new(Readers::new(path.to_string(), opts.max_readers)),
watcher: Arc::new(watcher),
db_path: PathBuf::from(path),
@@ -321,6 +321,8 @@ mod queue_tests;
#[cfg(test)]
mod scheduler_tests;
#[cfg(test)]
mod seam_tests;
#[cfg(test)]
mod stream_tests;
#[cfg(test)]
mod tx_tests;