perf(cron): memoize ensure_cron_project() per get_cli_sessions() scan

Pre-release Opus review on PR #1345 (Finding #3) flagged that
get_cli_sessions() was calling ensure_cron_project() once per cron
session in the loop — N lock acquires + N disk reads of projects.json
for N cron sessions per sidebar refresh.

Hoist a per-scan lazy memoizer (_cron_pid()) so we pay the resolution
cost at most once per get_cli_sessions() call. The memoizer is local
to the function (closure) so it's naturally scoped to a single scan
and doesn't leak across calls.

Could also have made ensure_cron_project() module-memoized, but that
would need invalidation on project deletion — the per-scan cache is
simpler and correct without coordination.
This commit is contained in:
nesquena-hermes
2026-04-30 17:21:51 +00:00
parent 77b456b755
commit c98fff79c2
+10 -1
View File
@@ -953,6 +953,15 @@ def get_cli_sessions() -> list:
except ImportError:
_cli_profile = None # older agent -- fall back to no profile
# Memoize the cron project ID for this scan so we don't pay a lock-acquire +
# disk-read of projects.json per cron session in the loop below.
# Resolved lazily on the first cron session we encounter.
_cron_pid_cache = [None] # list-as-cell so the closure can mutate
def _cron_pid():
if _cron_pid_cache[0] is None:
_cron_pid_cache[0] = ensure_cron_project()
return _cron_pid_cache[0]
try:
for row in read_importable_agent_session_rows(db_path, limit=200, log=logger, exclude_sources=None):
sid = row['id']
@@ -991,7 +1000,7 @@ def get_cli_sessions() -> list:
'updated_at': raw_ts,
'pinned': False,
'archived': False,
'project_id': ensure_cron_project() if is_cron_session(sid, _source) else None,
'project_id': _cron_pid() if is_cron_session(sid, _source) else None,
'profile': profile,
'source_tag': _source,
'raw_source': row.get('raw_source'),