perf(db): set the SQLite pragmas from a connect hook and clear WAL sidecars on db reset

This commit is contained in:
jamiepine
2026-10-04 00:00:35 +00:00
committed by capy-ai-staging[bot]
parent 36bb6c1ad7
commit ccc092bad0
3 changed files with 19 additions and 27 deletions
+13 -23
View File
@@ -1,10 +1,9 @@
"""Engine creation, initialization, and session management."""
import logging
import sqlite3 as _sqlite3
import uuid
from sqlalchemy import create_engine
from sqlalchemy import create_engine, event
from sqlalchemy.orm import sessionmaker
from .. import config
@@ -23,21 +22,6 @@ from .seed import backfill_generation_versions, seed_builtin_presets
logger = logging.getLogger(__name__)
def _make_connection(db_path: str) -> _sqlite3.Connection:
"""Open a SQLite connection with WAL journal mode and a 5-second busy timeout.
WAL allows concurrent readers while a write is in progress (the default
DELETE journal blocks all readers). This matters for voicebox because SSE
status polls and history queries run concurrently with the generation worker
writing to the same database. The busy timeout prevents "database is
locked" errors when two writers briefly contend on the same write slot.
"""
conn = _sqlite3.connect(db_path, check_same_thread=False)
conn.execute("PRAGMA journal_mode=WAL")
conn.execute("PRAGMA busy_timeout=5000")
return conn
# Initialized by init_db()
engine = None
SessionLocal = None
@@ -54,15 +38,21 @@ def init_db() -> None:
engine = create_engine(
f"sqlite:///{_db_path}",
connect_args={"check_same_thread": False},
# Each connection enables WAL journal mode and sets a 5-second busy
# timeout. WAL allows concurrent readers during a write (the default
# DELETE/ROLLBACK journal blocks all readers), which matters for
# voicebox because SSE status polls and history queries run
)
@event.listens_for(engine, "connect")
def _set_sqlite_pragmas(dbapi_connection, _record) -> None:
# Each pooled connection enables WAL journal mode and sets a 5-second
# busy timeout. WAL allows concurrent readers during a write (the
# default DELETE/ROLLBACK journal blocks all readers), which matters
# for voicebox because SSE status polls and history queries run
# concurrently with the generation worker writing to the same db.
# busy_timeout prevents "database is locked" errors when two
# connections briefly contend on the same write slot.
creator=lambda: _make_connection(str(_db_path)),
)
cursor = dbapi_connection.cursor()
cursor.execute("PRAGMA journal_mode=WAL")
cursor.execute("PRAGMA busy_timeout=5000")
cursor.close()
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)