From 8ed5e54f65c706d197d0ea554232d5071d0279df Mon Sep 17 00:00:00 2001 From: sebastianlutycz Date: Thu, 4 Jun 2026 14:52:36 +0000 Subject: [PATCH] perf(db): cache SQLite schema init and optimize descendant traversal - Cache SQLite schema initialization status process-wide in hermes_state.py to prevent redundant column reconciliations and FTS probe queries on every SessionDB connection creation. This eliminates SQLite lock contention under high concurrent requests (e.g. status polls). Bypassed in pytest/unittest environments for mock compatibility. - Optimize the _session_latest_descendant query in hermes_cli/web_server.py using a recursive CTE (WITH RECURSIVE) to query only descendants of the target session. This avoids downloading and parsing all historical sessions in Python. --- hermes_cli/web_server.py | 12 +++++++++++- hermes_state.py | 15 ++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/hermes_cli/web_server.py b/hermes_cli/web_server.py index d25ca164341..78aafbee50b 100644 --- a/hermes_cli/web_server.py +++ b/hermes_cli/web_server.py @@ -4478,7 +4478,17 @@ def _session_latest_descendant(session_id: str): rows = [] if conn is not None: raw_rows = conn.execute( - "SELECT id, parent_session_id, started_at FROM sessions" + """ + WITH RECURSIVE descendants(id, parent_session_id, started_at) AS ( + SELECT id, parent_session_id, started_at FROM sessions WHERE id = ? + UNION ALL + SELECT s.id, s.parent_session_id, s.started_at + FROM sessions s + JOIN descendants d ON s.parent_session_id = d.id + ) + SELECT id, parent_session_id, started_at FROM descendants WHERE id != ? + """, + (sid, sid) ).fetchall() for row in raw_rows: rows.append({ diff --git a/hermes_state.py b/hermes_state.py index f08acdce295..39a45194316 100644 --- a/hermes_state.py +++ b/hermes_state.py @@ -19,6 +19,7 @@ import logging import random import re import sqlite3 +import sys import threading import time from pathlib import Path @@ -72,6 +73,9 @@ _last_init_error_lock = threading.Lock() _wal_fallback_warned_paths: set[str] = set() _wal_fallback_warned_lock = threading.Lock() +_initialized_dbs: Dict[str, Dict[str, Any]] = {} +_db_init_lock = threading.Lock() + _FTS_TRIGGERS = ( "messages_fts_insert", "messages_fts_delete", @@ -421,7 +425,16 @@ class SessionDB: apply_wal_with_fallback(self._conn, db_label="state.db") self._conn.execute("PRAGMA foreign_keys=ON") - self._init_schema() + db_path_str = str(self.db_path.resolve()) + is_testing = "pytest" in sys.modules or "unittest" in sys.modules + with _db_init_lock: + if not is_testing and db_path_str in _initialized_dbs: + self._fts_enabled = _initialized_dbs[db_path_str]["fts_enabled"] + else: + self._init_schema() + _initialized_dbs[db_path_str] = { + "fts_enabled": self._fts_enabled + } except Exception as exc: # Capture the cause so /resume and friends can surface WHY the # session DB is unavailable instead of a bare "Session database