Fix StateManager deadlock with explicit BEGIN IMMEDIATE + retry
with conn: context manager in Python sqlite3 doesn't respect busy_timeout for the implicit BEGIN; under concurrent subprocess writes the transaction would fail immediately. Replace with explicit BEGIN IMMEDIATE + retry loop (6 attempts, 0.5s back-off) to handle WAL write contention.
This commit is contained in:
+18
-1
@@ -250,12 +250,29 @@ class StateManager:
|
||||
return
|
||||
|
||||
conn = self._get_write_conn()
|
||||
for attempt in range(6):
|
||||
try:
|
||||
with conn:
|
||||
conn.execute("BEGIN IMMEDIATE")
|
||||
for sql, params in batch:
|
||||
conn.execute(sql, params)
|
||||
conn.execute("COMMIT")
|
||||
return
|
||||
except sqlite3.OperationalError as e:
|
||||
try:
|
||||
conn.execute("ROLLBACK")
|
||||
except Exception:
|
||||
pass
|
||||
if attempt < 5:
|
||||
time.sleep(0.5 * (attempt + 1))
|
||||
else:
|
||||
logger.error("StateManager flush failed after 6 attempts (%d ops): %s", len(batch), e)
|
||||
except Exception:
|
||||
try:
|
||||
conn.execute("ROLLBACK")
|
||||
except Exception:
|
||||
pass
|
||||
logger.exception("StateManager flush failed (%d ops)", len(batch))
|
||||
return
|
||||
|
||||
def _writer_loop(self) -> None:
|
||||
"""Background loop: flush write queue every FLUSH_INTERVAL seconds."""
|
||||
|
||||
Reference in New Issue
Block a user