fix(tui_gateway): back off notification poller when session is busy

The busy-session branch of _notification_poller_loop re-queued the
completion event and immediately re-polled it with no sleep, spinning
at full speed (100% CPU, ~1100 futex/s of GIL churn) for as long as
the session stayed running. This starved the dashboard asyncio loop:
/api/status went from 0.14s to 3-6s with 10s timeouts.

Sleep 0.25s outside history_lock before re-polling, mirroring the
0.1s back-off already used for foreign-session events.
This commit is contained in:
Lucas Oliveira 2026-07-02 21:32:08 -03:00 committed by Teknium
parent 7ecc822e11
commit 98804dbeef

View file

@ -8487,11 +8487,19 @@ def _notification_poller_loop(
_emit("status.update", sid, {"kind": "process", "text": text})
_emitted.add(_dedup_key)
_requeued = False
with session["history_lock"]:
if session.get("running"):
process_registry.completion_queue.put(evt)
continue
session["running"] = True
_requeued = True
else:
session["running"] = True
if _requeued:
# Back off before re-polling: the re-queued event keeps the queue
# non-empty, so without a sleep this loop spins at full speed
# (100% CPU, GIL churn) for as long as the session stays busy.
time.sleep(0.25)
continue
rid = f"__notif__{int(time.time() * 1000)}"
try: