You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(agentex): end SSE subscriptions on terminal task; stop deleting shared stream
Task event SSE subscriptions had no terminal condition. stream_task_events ran
a `while True` loop whose only exits were client disconnect (CancelledError) and
fatal errors. Once a task finished its producer stopped writing, but the reader
kept blocking on the topic forever — issuing an XREAD every couple of seconds
and pinning one connection from the shared per-process Redis pool. Because the
stream key carries a sliding TTL, a finished task's key eventually disappears
while readers keep blocking on it, turning each subscription into a permanent
zombie. Accumulated zombies exhaust the pool, which is shared with the readiness
probe, so /readyz fails while the dependency-free /healthz keeps returning 200 —
the pod goes Unready and is never restarted.
Termination:
- Primary is event-driven. Every terminal transition funnels through
task_service.transition_status (and delete via update_task), which XADDs a
task_updated event carrying the new status onto the task's own stream. The
reader already delivers those events, so it returns as soon as it forwards one
whose task is in a terminal status — no DB lookup and no ordering race, since
the terminal event is the last message produced.
- Fallback runs on the keepalive-ping cadence for the cases the event path
cannot see: a client that connects after the task already finished, a producer
that dies without emitting a terminal event, or a task_updated with no task
payload. It ends the stream when the task is terminal or when a topic that had
existed is reclaimed. stream_ever_existed is seeded from the tail snapshot so a
mid-flight subscriber correctly arms the vanished-topic check.
Shared stream:
- Drop the per-subscriber cleanup_stream in finally. The topic is keyed only by
task id and shared by every viewer, so deleting it on one subscriber's exit
tore the stream out from under the others. The sliding TTL already reclaims it.
Also adds stream_exists to the stream port + Redis adapter (EXISTS) for the
vanished-topic fallback, and two integration regression tests: the stream ends
on its own once the task is terminal, and a single subscriber disconnecting does
not delete the shared topic.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
0 commit comments