db: thread-local SQLite connections + busy_timeout
The module-level _conn was being hit from FastAPI handlers, the retention daemon thread, and asyncio.to_thread workers simultaneously. Sharing a single sqlite3.Connection across threads is unsafe (cursors collide) even with check_same_thread=False and WAL. The writer _lock didn't cover readers, so a reader cursor could race a writer mid-statement. Switch to threading.local(): each thread gets its own Connection via _get_conn(). WAL handles concurrent readers/writer at the DB level; busy_timeout=5000 absorbs short-lived "database is locked" when two threads both try to BEGIN IMMEDIATE. The write-serialising _lock stays — it keeps multi-statement writer blocks atomic and avoids busy-loop on concurrent writers. External access via db._conn replaced with a new db.has_running_application helper (the only caller outside db.py). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6bd7a4306a
commit
617c76cb54
2 changed files with 88 additions and 72 deletions
|
|
@ -274,11 +274,7 @@ def _filter_summary(f) -> str:
|
|||
|
||||
|
||||
def _has_running_application(user_id: int) -> bool:
|
||||
row = db._conn.execute(
|
||||
"SELECT 1 FROM applications WHERE user_id = ? AND finished_at IS NULL LIMIT 1",
|
||||
(user_id,),
|
||||
).fetchone()
|
||||
return row is not None
|
||||
return db.has_running_application(user_id)
|
||||
|
||||
|
||||
def _finish_apply_background(app_id: int, user_id: int, flat_id: str, url: str,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue