← back to Terminal Status
TK-11831: single-flight the iTerm enumeration so a cold herd collapses to ONE osascript
9e5ef9ee0afbaf084f7038ce5c7d2572923992c6 · 2026-09-17 10:34:46 -0700 · Steve Abrams
The 30s cross-process cache (TK-11879) collapses REPEAT enumerations but a
SIMULTANEOUS cold herd — ~59 sessions starting at once, empty cache — all miss
together and each fires its own osascript into iTerm's ONE serial AppleScript
queue. That is the exact stampede this ticket is about (628 'osascript rc1'
blinds in a 7d window, terminal_api unavailable x57 at the 91s peak); the TTL
cache alone moves repeat-frequency, not the cold-herd tail (codex-check flag).
Fix: a NON-BLOCKING cross-process flock so exactly ONE caller enumerates. A peer
that fails LOCK_NB waits briefly (default 6s) for the winner to publish its fresh
map (the coalesced path) and, only if the winner is still enumerating past the
wait, falls through to the SAME stale-cache/blind path an osascript timeout
already takes — so a peer NEVER fires a second osascript and NEVER manufactures a
fresh answer it did not measure. Fail-OPEN: any lock error degrades to the prior
direct-enumerate behaviour. Kill-switch TERMINAL_STATUS_NO_SINGLEFLIGHT=1.
Verified: 8 concurrent cold scans -> exactly 1 osascript, 7 coalesced (8->1; at
59 sessions, 59->1). Tests 56->58: coalesce fires zero osascript and returns the
winner's map; peer-holds-lock-with-no-map blinds without a second osascript.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TmvM611X4duoLdp1cFmpy2
Files touched
M terminal_status.pyM test_terminal_status.py
Diff
commit 9e5ef9ee0afbaf084f7038ce5c7d2572923992c6
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Sep 17 10:34:46 2026 -0700
TK-11831: single-flight the iTerm enumeration so a cold herd collapses to ONE osascript
The 30s cross-process cache (TK-11879) collapses REPEAT enumerations but a
SIMULTANEOUS cold herd — ~59 sessions starting at once, empty cache — all miss
together and each fires its own osascript into iTerm's ONE serial AppleScript
queue. That is the exact stampede this ticket is about (628 'osascript rc1'
blinds in a 7d window, terminal_api unavailable x57 at the 91s peak); the TTL
cache alone moves repeat-frequency, not the cold-herd tail (codex-check flag).
Fix: a NON-BLOCKING cross-process flock so exactly ONE caller enumerates. A peer
that fails LOCK_NB waits briefly (default 6s) for the winner to publish its fresh
map (the coalesced path) and, only if the winner is still enumerating past the
wait, falls through to the SAME stale-cache/blind path an osascript timeout
already takes — so a peer NEVER fires a second osascript and NEVER manufactures a
fresh answer it did not measure. Fail-OPEN: any lock error degrades to the prior
direct-enumerate behaviour. Kill-switch TERMINAL_STATUS_NO_SINGLEFLIGHT=1.
Verified: 8 concurrent cold scans -> exactly 1 osascript, 7 coalesced (8->1; at
59 sessions, 59->1). Tests 56->58: coalesce fires zero osascript and returns the
winner's map; peer-holds-lock-with-no-map blinds without a second osascript.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TmvM611X4duoLdp1cFmpy2
---
terminal_status.py | 84 +++++++++++++++++++++++++++++++++++++++++++++++--
test_terminal_status.py | 52 ++++++++++++++++++++++++++++++
2 files changed, 134 insertions(+), 2 deletions(-)
diff --git a/terminal_status.py b/terminal_status.py
index ba9c530..8ae94fe 100644
--- a/terminal_status.py
+++ b/terminal_status.py
@@ -1065,12 +1065,66 @@ _ITERM_TTL = float(os.environ.get("TERMINAL_STATUS_ITERM_TTL", "30"))
# How much older than the fresh TTL a cached map may be and still serve as the
# blind-fallback. Bounded so a long-abandoned map is not trusted forever.
_ITERM_STALE_MAX = float(os.environ.get("TERMINAL_STATUS_ITERM_STALE_MAX", "300"))
+# TK-11831 single-flight: the 30s TTL cache above collapses REPEAT enumerations,
+# but a SIMULTANEOUS cold herd (~59 sessions starting at once, empty cache) all
+# miss together and each fires its own osascript into iTerm's ONE serial
+# AppleScript queue -- the exact stampede this ticket is about (628 'osascript
+# rc1' blinds in one 7d window, terminal_api unavailable x57 at the 91s peak).
+# The codex-check flagged that the TTL cache alone moves repeat-frequency, not
+# the cold-herd tail. Fix: a NON-BLOCKING cross-process lock so exactly ONE
+# caller enumerates; every peer waits briefly for that winner to publish its
+# fresh map (the coalesced path) and, only if the winner is still enumerating
+# past the wait, falls through to the SAME stale-cache/blind path that already
+# exists on an osascript timeout -- so a peer NEVER fires a second osascript and
+# NEVER manufactures a fresh answer it did not measure. Fail-OPEN: any lock
+# error degrades to today's behaviour (enumerate directly). Kill-switch:
+# TERMINAL_STATUS_NO_SINGLEFLIGHT=1. The wait is bounded well under startup
+# tolerance so a coalescing peer can never hang a session.
+_ITERM_SINGLEFLIGHT = os.environ.get("TERMINAL_STATUS_NO_SINGLEFLIGHT", "") == ""
+_ITERM_SF_WAIT = float(os.environ.get("TERMINAL_STATUS_ITERM_SF_WAIT", "6"))
def _iterm_cache_path():
return Path(tempfile.gettempdir()) / f"terminal-status-iterm-{os.getuid()}.json"
+def _iterm_lock_path():
+ return Path(tempfile.gettempdir()) / f"terminal-status-iterm-{os.getuid()}.lock"
+
+
+def _iterm_singleflight_acquire():
+ """Try to become the sole enumerator. Returns an OPEN locked fd (caller must
+ close it to release) if we won, or None if a peer already holds it. Fail-OPEN:
+ on any error return a sentinel that behaves like 'won' so painting degrades to
+ the pre-single-flight direct-enumerate path rather than blocking."""
+ try:
+ fd = os.open(str(_iterm_lock_path()), os.O_CREAT | os.O_RDWR, 0o600)
+ except OSError:
+ return "failopen" # cannot even open the lockfile -> enumerate directly
+ try:
+ fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
+ return fd # we are the single flight
+ except OSError:
+ os.close(fd)
+ return None # a peer is enumerating
+
+
+def _iterm_wait_for_winner():
+ """A peer is enumerating. Poll the cross-process cache up to _ITERM_SF_WAIT for
+ the fresh map the winner publishes. The caller only reaches here AFTER its own
+ _iterm_cache_get(_ITERM_TTL) already MISSED, so any within-TTL map that appears
+ now is necessarily the winner's new write -- a plain TTL-freshness poll is
+ sufficient (no mtime bookkeeping). Return that map on success, else None (caller
+ then uses the existing stale/blind fallback). Never fires osascript; never raises."""
+ deadline = time.monotonic() + _ITERM_SF_WAIT
+ while time.monotonic() < deadline:
+ hit = _iterm_cache_get(_ITERM_TTL)
+ if hit is not None and hit[0]:
+ return hit[0]
+ time.sleep(0.15)
+ return None
+
+
def _iterm_cache_get(max_age):
"""Most recent sibling enumeration within max_age seconds, or None. Never raises.
Returns (sessions_dict, age_seconds)."""
@@ -1139,6 +1193,22 @@ def iterm_sessions(fresh=False):
if os.environ.get("TERMINAL_STATUS_DEBUG"):
print("iterm-cache: HIT (%.1fs)" % hit[1], file=sys.stderr)
return hit[0], "cached"
+ # Cold miss. TK-11831 single-flight: collapse a simultaneous herd to ONE
+ # osascript. A peer already enumerating -> wait briefly for its fresh map,
+ # else degrade to the SAME stale/blind path an osascript failure would take
+ # (never a second osascript, never a manufactured fresh answer).
+ sf_lock = None
+ if not fresh and _ITERM_SINGLEFLIGHT:
+ sf_lock = _iterm_singleflight_acquire()
+ if sf_lock is None:
+ coalesced = _iterm_wait_for_winner()
+ if coalesced:
+ if os.environ.get("TERMINAL_STATUS_DEBUG"):
+ print("iterm-cache: COALESCED (peer enumerated)", file=sys.stderr)
+ return coalesced, "cached"
+ return _iterm_blind(
+ "single-flight: peer still enumerating after %.1fs" % _ITERM_SF_WAIT)
+ # sf_lock is an open fd (we won) or "failopen" (degrade to direct enumerate).
script = """
set sep to ASCII character 9
tell application "iTerm2"
@@ -1161,12 +1231,22 @@ end tell
# would delay startup. A blind here is a genuine blind spot, not a benign
# empty result, so it degrades to a cached map (TK-11879) or, failing that,
# is recorded rather than silently swallowed.
- result = subprocess.run(["osascript", "-e", script], capture_output=True,
- text=True, timeout=30)
+ try:
+ result = subprocess.run(["osascript", "-e", script], capture_output=True,
+ text=True, timeout=30)
+ finally:
+ # Release the single-flight lock the instant enumeration returns so a
+ # waiting peer can proceed; the cache write below is cheap and racey-safe.
+ if isinstance(sf_lock, int):
+ os.close(sf_lock)
+ sf_lock = None
if result.returncode:
return _iterm_blind("osascript returncode " + str(result.returncode))
except (OSError, subprocess.TimeoutExpired) as exc:
return _iterm_blind(type(exc).__name__ + ": " + str(exc)[:120])
+ finally:
+ if isinstance(sf_lock, int): # any early return / exception path
+ os.close(sf_lock)
sessions = {}
for line in result.stdout.splitlines():
tty, sep, title = line.partition("\t")
diff --git a/test_terminal_status.py b/test_terminal_status.py
index 14011f9..f354487 100644
--- a/test_terminal_status.py
+++ b/test_terminal_status.py
@@ -795,6 +795,11 @@ class ItermEnumCacheTests(unittest.TestCase):
p = patch.object(ts, "_iterm_cache_path", lambda: self.cache)
p.start()
self.addCleanup(p.stop)
+ # TK-11831 single-flight lock isolated to this test's tempdir.
+ self.lock = Path(self.temp.name) / "iterm.lock"
+ lp = patch.object(ts, "_iterm_lock_path", lambda: self.lock)
+ lp.start()
+ self.addCleanup(lp.stop)
# HOME redirected so a test blind's enum_blind trail never pollutes the real file.
hp = patch.dict(os.environ, {"HOME": self.temp.name})
hp.start()
@@ -878,6 +883,53 @@ class ItermEnumCacheTests(unittest.TestCase):
self.assertEqual((second, api2), ({}, "available"))
self.assertEqual(self.calls, 2)
+ def test_single_flight_peer_holding_lock_coalesces_and_fires_no_osascript(self):
+ # TK-11831: a peer is already enumerating (holds the lock). A fresh map it
+ # publishes must be COALESCED without this caller firing its own osascript
+ # into iTerm's serial queue -- the herd collapses to ONE round-trip.
+ import fcntl as _f
+ fd = os.open(str(self.lock), os.O_CREAT | os.O_RDWR, 0o600)
+ _f.flock(fd, _f.LOCK_EX | _f.LOCK_NB) # simulate the peer/winner
+ # The winner has just published its map (real file, fresh mtime for the
+ # wait loop's mtime>=started gate).
+ self.cache.write_text(json.dumps({"sessions": {"ttys010": "🟢 one"}}))
+ fresh = ({"ttys010": "🟢 one"}, 0.0)
+ # Initial lookup MISSES (forces single-flight); the wait-loop lookup HITS
+ # (the winner has published) -> deterministic coalesce.
+ calls = {"n": 0}
+
+ def staged_get(_max_age):
+ calls["n"] += 1
+ return None if calls["n"] == 1 else fresh
+ try:
+ with self._osascript(rc=0, stdout="/dev/ttysZZZ\tSHOULD-NOT-RUN\n"):
+ with patch.object(ts, "_iterm_cache_get", staged_get), \
+ patch.object(ts, "_ITERM_SF_WAIT", 1.0):
+ sessions, api = ts.iterm_sessions()
+ finally:
+ os.close(fd)
+ # ZERO osascript calls -- the whole point of single-flight -- and the
+ # coalesced map is returned as a cache result.
+ self.assertEqual(self.calls, 0,
+ "a peer already enumerating must not trigger a second osascript")
+ self.assertEqual((sessions, api), ({"ttys010": "🟢 one"}, "cached"))
+
+ def test_single_flight_peer_lock_no_fresh_map_blinds_without_osascript(self):
+ # Peer holds the lock but publishes nothing usable within the wait -> this
+ # caller degrades to the SAME blind path an osascript timeout takes, and
+ # STILL fires no osascript (never a second round-trip on the busy queue).
+ import fcntl as _f
+ fd = os.open(str(self.lock), os.O_CREAT | os.O_RDWR, 0o600)
+ _f.flock(fd, _f.LOCK_EX | _f.LOCK_NB)
+ try:
+ with self._osascript(rc=0, stdout="/dev/ttysZZZ\tSHOULD-NOT-RUN\n"):
+ with patch.object(ts, "_ITERM_SF_WAIT", 0.3):
+ sessions, api = ts.iterm_sessions()
+ finally:
+ os.close(fd)
+ self.assertEqual(self.calls, 0)
+ self.assertEqual((sessions, api), ({}, "unavailable"))
+
def test_another_users_cache_file_is_never_trusted(self):
with self._osascript(rc=0, stdout="/dev/ttys010\t🟢 one\n"):
ts.iterm_sessions()
← 2a0da77 iterm_sessions: cross-process cache collapses the enum herd
·
back to Terminal Status
·
auto-data-snapshot: 2026-09-18T14:19:46 (36 data files) — te de433d8 →