fix(code-runtime-python): keep the reply pump alive past a closed thread loop

A binding called from a worker thread records that thread's loop for its reply.
If the thread finished and closed its loop before the host reply arrived,
_pump_replies' call_soon_threadsafe onto the closed loop raises RuntimeError;
unguarded, that ends the pump task and strands every later reply. Wrap the
schedule in a try/except that drops the moot reply (nothing awaits it) and keeps
the pump serving.
This commit is contained in:
Chinesezjc
2026-08-31 14:21:57 +08:00
committed by Tianyi Cui
parent 3a560d37a6
commit a30b460b37
@@ -877,7 +877,17 @@ async def _pump_replies(
ok = bool(frame.get("ok"))
value = frame.get("value")
message = frame.get("message")
loop.call_soon_threadsafe(complete, fut, ok, value, message)
try:
loop.call_soon_threadsafe(complete, fut, ok, value, message)
except RuntimeError:
# The Future's loop has already closed — the thread that ran
# `asyncio.run(tools.x(...))` finished (its coroutine was cancelled
# or it exited) before this reply arrived, so nothing awaits the
# Future and the reply is moot. Drop it; scheduling onto a closed
# loop raises RuntimeError, and letting that escape would kill the
# pump and strand every later reply — the exact failure class this
# cross-loop delivery exists to prevent.
continue
_SCALAR_RE = re.compile(