[object Object]

← back to Terminal Status

terminal-status: fix paint hang — raise per-process PROC_TTL 5s→120s so a single paint scans once, not twice

9696608ddf19e3c8bced18ae410401db7924ab1b · 2026-09-11 12:07:07 -0700 · Steve Abrams

The 5s cache TTL was shorter than the ~15s (up to 60s) process-table scan, so the
second intra-run processes() call always found the cache expired and re-scanned —
every paint paid the scan twice (~120s worst case), leaving a stale two-dot
transient on the tab during the slow paint. The cache is per-process (reset each
invocation), so a larger TTL only bridges the two calls within one run with zero
cross-invocation staleness. Verified: paint 120s→13.3s (single scan).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DSZgKJ86hmzguEeX8iqoZi

Files touched

Diff

commit 9696608ddf19e3c8bced18ae410401db7924ab1b
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Fri Sep 11 12:07:07 2026 -0700

    terminal-status: fix paint hang — raise per-process PROC_TTL 5s→120s so a single paint scans once, not twice
    
    The 5s cache TTL was shorter than the ~15s (up to 60s) process-table scan, so the
    second intra-run processes() call always found the cache expired and re-scanned —
    every paint paid the scan twice (~120s worst case), leaving a stale two-dot
    transient on the tab during the slow paint. The cache is per-process (reset each
    invocation), so a larger TTL only bridges the two calls within one run with zero
    cross-invocation staleness. Verified: paint 120s→13.3s (single scan).
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01DSZgKJ86hmzguEeX8iqoZi
---
 terminal_status.py | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/terminal_status.py b/terminal_status.py
index 3346de7..87cf3b1 100644
--- a/terminal_status.py
+++ b/terminal_status.py
@@ -152,8 +152,19 @@ class Process:
 # cross-process file cache would, but a table up to TTL seconds stale could
 # fail to see a just-started session and wrongly report "no owning terminal",
 # so it is not worth the risk here.
+#
+# TK-11466-followup (2026-09-11): the 5s default DEFEATED this cache's own
+# purpose. The scan is ~15s (up to the 60s ps ceiling under load), so by the
+# time the SECOND intra-run call arrives the 5s window has already expired and
+# it re-scans anyway -- every paint paid the scan TWICE, which is the ~120s
+# hang that let a slow paint leave a stale "two dots" transient on the tab.
+# The TTL must exceed one worst-case scan to bridge the two calls WITHIN a run.
+# This is a per-PROCESS cache reset each invocation, so a large value only means
+# "reuse the one scan across this single run's two calls" -- it has ZERO
+# cross-invocation staleness effect (the just-started-session risk above is
+# about a cross-PROCESS file cache, which this is not). 120s = 60s ceiling x2.
 _PROC_CACHE = {"at": 0.0, "rows": None}
-_PROC_TTL = float(os.environ.get("TERMINAL_STATUS_PROC_TTL", "5"))
+_PROC_TTL = float(os.environ.get("TERMINAL_STATUS_PROC_TTL", "120"))
 
 
 def processes(fresh=False):

← 1bc426c set-variant: --tty targeting + don't require caller ancestry  ·  back to Terminal Status  ·  terminal-status: cross-process proc-table cache + negative-r ce04960 →