fix(peewee): enable WAL journal mode for SQLite#132
Conversation
PeeweeStorage was using SQLite's default DELETE journal mode, while SqliteStorage already had WAL enabled. Without WAL, concurrent read/write access from threaded Flask causes frequent "database is locked" errors, leading to 500 responses and watcher retry storms.
Greptile SummaryThis PR enables WAL journal mode for Confidence Score: 5/5Safe to merge — minimal, well-targeted change with no correctness risks. The only finding is a P2 style suggestion: No files require special attention. Important Files Changed
Sequence DiagramsequenceDiagram
participant Flask Thread 1
participant Flask Thread 2
participant PeeweeStorage
participant SQLite (WAL)
Flask Thread 1->>PeeweeStorage: heartbeat (insert event)
Flask Thread 2->>PeeweeStorage: heartbeat (insert event)
PeeweeStorage->>SQLite (WAL): BEGIN WRITE (Thread 1)
PeeweeStorage->>SQLite (WAL): BEGIN READ (Thread 2)
Note over SQLite (WAL): WAL allows concurrent reader + writer
SQLite (WAL)-->>PeeweeStorage: OK (Thread 2 reads)
SQLite (WAL)-->>PeeweeStorage: OK (Thread 1 writes)
Note over SQLite (WAL): Checkpoint every 100 pages
|
SQLite's default of 1000 pages is fine; setting 100 would cause more frequent checkpointing and unnecessary IO.
Summary
SqliteStoragealready had WAL enabled, butPeeweeStorage(the default backend) did notProblem
Without WAL mode, SQLite uses DELETE journal mode which requires exclusive locks for writes. When aw-server's threaded Flask handles concurrent heartbeats from multiple watchers, this causes frequent
sqlite3.OperationalError: database is lockederrors.On one system, this resulted in:
Fix
WAL mode allows concurrent readers and a single writer without blocking, dramatically reducing contention. This is a one-line change to pass
pragmas={"journal_mode": "wal"}toSqliteExtDatabase.init().Test plan
sqlite3 <db-path> "PRAGMA journal_mode;"should returnwalRelated: ActivityWatch/aw-server#151