fix: close leaked state.db read-only connections in session discoverability/recovery
Three sites used `with sqlite3.connect(f"file:...?mode=ro", uri=True) as conn:`, which only scopes the transaction — sqlite3.Connection's context manager never calls close(). Same recurring bug class as #1421/#1494/#2233/#3904. On a long-lived server each poll leaked a state.db (+ -wal/-shm) fd until the process hit macOS's 256 soft FD limit and writes started failing. Wrap all three in contextlib.closing(), matching the pattern already used elsewhere in these files.
This commit is contained in:
1 parent
5f3117f81e
commit
dcf881f1e8
2 files changed
+5
-3
No files matched your search
@@ -17,6 +17,7 @@ import threading
|
||||
import shutil
|
||||
import sqlite3
|
||||
from collections import Counter
|
||||
from contextlib import closing
|
||||
from pathlib import Path
|
||||
from typing import Iterable
|
||||
|
||||
@@ -102,7 +103,7 @@ def _read_state_db(state_db_path: Path | None) -> dict[str, dict]:
|
||||
if state_db_path is None or not state_db_path.exists():
|
||||
return {}
|
||||
try:
|
||||
with sqlite3.connect(f"file:{state_db_path}?mode=ro", uri=True) as conn:
|
||||
with closing(sqlite3.connect(f"file:{state_db_path}?mode=ro", uri=True)) as conn:
|
||||
conn.row_factory = sqlite3.Row
|
||||
tables = {row[0] for row in conn.execute("select name from sqlite_master where type='table'")}
|
||||
if "sessions" not in tables:
|
||||
|
||||
@@ -32,6 +32,7 @@ import os
|
||||
import shutil
|
||||
import sqlite3
|
||||
import threading
|
||||
from contextlib import closing
|
||||
from pathlib import Path
|
||||
|
||||
from api.turn_journal import (
|
||||
@@ -381,7 +382,7 @@ def _state_db_has_session(session_id: str, state_db_path: Path | None) -> bool:
|
||||
if state_db_path is None or not state_db_path.exists():
|
||||
return True
|
||||
try:
|
||||
with sqlite3.connect(f"file:{state_db_path}?mode=ro", uri=True) as conn:
|
||||
with closing(sqlite3.connect(f"file:{state_db_path}?mode=ro", uri=True)) as conn:
|
||||
cur = conn.execute(
|
||||
"select 1 from sqlite_master where type='table' and name='sessions'"
|
||||
)
|
||||
@@ -446,7 +447,7 @@ def _read_state_db_missing_sidecar_rows(
|
||||
if state_db_path is None or not state_db_path.exists():
|
||||
return []
|
||||
try:
|
||||
with sqlite3.connect(f"file:{state_db_path}?mode=ro", uri=True) as conn:
|
||||
with closing(sqlite3.connect(f"file:{state_db_path}?mode=ro", uri=True)) as conn:
|
||||
conn.row_factory = sqlite3.Row
|
||||
session_cols = {row[1] for row in conn.execute("PRAGMA table_info(sessions)").fetchall()}
|
||||
message_cols = {row[1] for row in conn.execute("PRAGMA table_info(messages)").fetchall()}
|
||||
|
||||
Reference in new issue
Block a user