From 7791370d49af8a63393d86ed2d253f86ef09ea3f Mon Sep 17 00:00:00 2001 From: nesquena-hermes Date: Thu, 25 Jun 2026 21:51:07 +0000 Subject: [PATCH] =?UTF-8?q?docs(#4908):=20correct=20cache-invalidation=20c?= =?UTF-8?q?omment=20per=20Opus=20gate=20=E2=80=94=20TTL=20is=20the=20backs?= =?UTF-8?q?top=20for=20externally-driven=20changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Opus SHIP-WITH-FIXES (no code change required): the comment/docstring overstated that the session-list-change listener covers ALL structural mutations. In-app mutations fire it, but externally-driven changes (scheduled cron completion, external CLI writes) don't — for those the 30s streaming TTL is the load-bearing backstop (≤30s bounded, self-healing lag). Comment-only accuracy fix; logic unchanged (both gates: perf fix correct, freeze effective, staleness bounded). --- api/models.py | 7 +++++-- api/routes.py | 15 ++++++++++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/api/models.py b/api/models.py index d55e7555..3b0220b5 100644 --- a/api/models.py +++ b/api/models.py @@ -4256,8 +4256,11 @@ def _cli_sessions_streaming_freeze_marker(): a stream starts/stops (so the just-finished turn's rows are picked up promptly). A streaming session's own CLI/cron title/count is not what this projection returns (the streaming session is overlaid live by the route layer), and any - structural mutation invalidates the cache directly via - ``clear_cli_sessions_cache``, so nothing user-visible lags under the freeze. (#4842) + in-app structural mutation invalidates the cache directly via + ``clear_cli_sessions_cache``. Externally-driven changes that don't fire that + listener (a scheduled cron completing, an external CLI writing rows) surface + within one streaming-TTL window (≤30s) rather than instantly — a bounded, + self-healing lag that is the deliberate latency/CPU trade-off of the freeze. (#4842) """ try: active = _active_stream_ids() diff --git a/api/routes.py b/api/routes.py index f26737f6..82250ce1 100644 --- a/api/routes.py +++ b/api/routes.py @@ -208,11 +208,16 @@ def _on_session_list_changed(profile: str | None = None) -> None: # #4842: also drop the inner CLI/cron projection cache. While a turn streams # that cache is frozen on a stable streaming marker (so per-token message # writes don't bust it), which means it no longer self-invalidates via the - # state.db content fingerprint mid-stream. Structural mutations (cron - # completion, new/renamed/archived sessions, attention) DO fire this - # listener — and never fire per streamed token — so clearing here restores - # prompt freshness for real changes without reintroducing the per-poll - # rebuild the freeze removed. + # state.db content fingerprint mid-stream. In-app structural mutations + # (session create/rename/archive/delete/branch/pin/move/import, attention) + # fire this listener — and never fire per streamed token — so clearing here + # restores prompt freshness for those without reintroducing the per-poll + # rebuild the freeze removed. Note: externally-driven changes that do NOT go + # through this listener (a scheduled cron job completing, or an external CLI + # writing rows directly) are not cleared here mid-stream; for those the 30s + # streaming TTL is the backstop — they surface within one streaming-TTL + # window (≤30s) rather than instantly. That bound is the deliberate + # latency/CPU trade-off of the freeze. try: from api.models import clear_cli_sessions_cache clear_cli_sessions_cache()