Commit 7b118b5
committed
fix: cancel RunResultStreaming on retry to prevent leaked asyncio tasks
When stream_events() is interrupted by a timeout and we retry, the old
RunResultStreaming object's _run_impl_task continues running as a dangling
asyncio.Task. Calling aclose() on the stream_events() async generator
throws GeneratorExit which skips the SDK's _cleanup_tasks() call, so
the background task is never cancelled.
Each timeout retry leaked one task still streaming from the API and
holding MCP server references. On process exit, asyncio.run() blocks
trying to clean up these orphaned tasks — a likely contributor to the
post-completion hangs requiring watchdog intervention.
Fix: call result.cancel() in the finally block after aclose(). This
cancels _run_impl_task, input/output guardrail tasks, and clears the
event queue before retrying with a fresh RunResultStreaming.1 parent 84ecf1d commit 7b118b5
1 file changed
Lines changed: 7 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
436 | 436 | | |
437 | 437 | | |
438 | 438 | | |
| 439 | + | |
439 | 440 | | |
440 | 441 | | |
441 | 442 | | |
| |||
464 | 465 | | |
465 | 466 | | |
466 | 467 | | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
467 | 474 | | |
468 | 475 | | |
469 | 476 | | |
| |||
0 commit comments