Release v0.51.329 — Release KS (#3814 O(n) index map + #3815 startup recovery skip) (#3840)
Some checks failed
Release & Docker / release (push) Has been cancelled

#3814: O(n) index-count map for /api/sessions. #3815: skip backup-less sidecars on startup recovery. Full suite 8275, Codex SAFE, Opus SHIP, CI 11/11. Co-authored-by: ai-ag2026 <ai-ag2026@users.noreply.github.com>
This commit is contained in:
nesquena-hermes
2026-06-08 11:49:26 -07:00
committed by GitHub
parent 7674bfb449
commit a0e5b9042f
5 changed files with 158 additions and 27 deletions

View File

@@ -513,24 +513,41 @@ def _read_metadata_json_prefix(path, max_prefix_bytes=65536):
def _lookup_index_message_count(session_id):
"""Return the indexed message count without loading the full session file."""
try:
entries = json.loads(SESSION_INDEX_FILE.read_text(encoding='utf-8'))
except Exception:
return None
return _index_message_count_map().get(str(session_id))
def _index_message_count_map(entries=None) -> dict[str, int]:
"""Return indexed message counts keyed by session id.
``load_metadata_only()`` is called in loops for stale lineage/sidebar rows.
Reading and parsing ``_index.json`` once per row turns /api/sessions into an
accidental O(n²) poll for old sidecars that predate persisted
``message_count``. Accepting already-loaded index rows lets callers reuse
the index they just parsed.
"""
if entries is None:
try:
entries = json.loads(SESSION_INDEX_FILE.read_text(encoding='utf-8'))
except Exception:
return {}
if not isinstance(entries, list):
return None
return {}
counts: dict[str, int] = {}
for entry in entries:
if entry.get('session_id') != session_id:
if not isinstance(entry, dict):
continue
sid = str(entry.get('session_id') or '')
if not sid:
continue
count = entry.get('message_count')
if isinstance(count, int) and count >= 0:
return count
try:
count = int(count)
except (TypeError, ValueError):
return None
return count if count >= 0 else None
return None
if not isinstance(count, int):
try:
count = int(count)
except (TypeError, ValueError):
continue
if count >= 0:
counts[sid] = count
return counts
def _parse_nonnegative_int(value):
@@ -791,7 +808,7 @@ class Session:
return session
@classmethod
def load_metadata_only(cls, sid):
def load_metadata_only(cls, sid, *, index_message_counts=None):
"""Load only the compact metadata fields, skipping the messages array.
Session JSON files have metadata fields (session_id, title, model, etc.)
@@ -820,7 +837,10 @@ class Session:
sidecar_message_count = _parse_nonnegative_int(parsed.get('message_count'))
index_message_count = None
if sidecar_message_count is None:
index_message_count = _lookup_index_message_count(sid)
if index_message_counts is not None:
index_message_count = index_message_counts.get(str(sid))
else:
index_message_count = _lookup_index_message_count(sid)
# Modern sidecars carry an accurate message_count, so it is the
# source of truth and we skip the per-row _index.json read in the
# common case. The sidebar index is only a cache (it can lag behind
@@ -2728,7 +2748,11 @@ def _stale_snapshot_metadata_refresh_ids(sessions: list[dict]) -> set[str]:
return refresh_ids
def _refresh_index_rows_from_sidecar_metadata(sessions: list[dict]) -> list[dict]:
def _refresh_index_rows_from_sidecar_metadata(
sessions: list[dict],
*,
index_message_counts: dict[str, int] | None = None,
) -> list[dict]:
"""Overlay fuller sidecar metadata onto stale sidebar index rows.
``_index.json`` is a cache and can lag behind the canonical session sidecar
@@ -2749,7 +2773,10 @@ def _refresh_index_rows_from_sidecar_metadata(sessions: list[dict]) -> list[dict
if not sid:
out.append(session)
continue
sidecar = Session.load_metadata_only(sid)
sidecar = Session.load_metadata_only(
sid,
index_message_counts=index_message_counts,
)
if not sidecar:
out.append(session)
continue
@@ -3051,7 +3078,11 @@ def all_sessions(diag=None):
active_stream_ids=active_stream_ids,
)
_diag_stage(diag, "all_sessions.refresh_sidecar_metadata")
refreshed_index_rows = _refresh_index_rows_from_sidecar_metadata(list(index_map.values()))
index_message_counts = _index_message_count_map(index)
refreshed_index_rows = _refresh_index_rows_from_sidecar_metadata(
list(index_map.values()),
index_message_counts=index_message_counts,
)
index_map = {
row['session_id']: row
for row in refreshed_index_rows