From ebc01222649935809e571e9d1aa99ce13c221850 Mon Sep 17 00:00:00 2001 From: YoursFunny Date: Sat, 8 Aug 2026 20:26:07 +0800 Subject: [PATCH] db: enable WAL and index the pending-task lease query The lease/earliest_run_after queries full-scanned tasks, and the rollback journal blocked readers behind worker writes. journal_mode=WAL (persistent, idempotent) plus idx_tasks_pending(status, run_after) covers both without a schema migration. --- crates/xmedia-bot/src/db.rs | 4 ++++ crates/xmedia-bot/src/queue.rs | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/crates/xmedia-bot/src/db.rs b/crates/xmedia-bot/src/db.rs index 36844a1..6d783a4 100644 --- a/crates/xmedia-bot/src/db.rs +++ b/crates/xmedia-bot/src/db.rs @@ -16,6 +16,10 @@ use std::time::Duration; pub fn open_db(path: &str) -> rusqlite::Result { let conn = Connection::open(path)?; conn.busy_timeout(Duration::from_secs(5))?; + // WAL lets readers run alongside writer leases instead of blocking on + // the rollback journal; the mode persists in the DB header, so the + // idempotent pragma here and in ensure_schema only needs to win once. + conn.pragma_update(None, "journal_mode", "WAL")?; Ok(conn) } diff --git a/crates/xmedia-bot/src/queue.rs b/crates/xmedia-bot/src/queue.rs index 919acb9..6250ff7 100644 --- a/crates/xmedia-bot/src/queue.rs +++ b/crates/xmedia-bot/src/queue.rs @@ -83,9 +83,11 @@ fn scaled_retry_delay(base: f64, attempts: i32) -> f64 { fn ensure_schema(conn: &rusqlite::Connection) -> rusqlite::Result<()> { conn.execute_batch( - "CREATE TABLE IF NOT EXISTS tasks (id TEXT PRIMARY KEY, payload TEXT NOT NULL, \ + "PRAGMA journal_mode=WAL; \ + CREATE TABLE IF NOT EXISTS tasks (id TEXT PRIMARY KEY, payload TEXT NOT NULL, \ run_after REAL NOT NULL, attempts INTEGER NOT NULL, status TEXT NOT NULL, \ - locked_until REAL NOT NULL, created_at REAL NOT NULL);", + locked_until REAL NOT NULL, created_at REAL NOT NULL); \ + CREATE INDEX IF NOT EXISTS idx_tasks_pending ON tasks(status, run_after);", ) }