Retire a worker whose pipe broke rather than hand it on

poll() still calls a child that has exited but not been reaped alive, so a
node that ended itself with os._exit left its corpse on the idle queue and
the next call died on a broken pipe. Mark it the way the out-of-step paths
already do, and _release replaces it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-24 14:55:59 +02:00
co-authored by Claude Opus 5
parent a4fddb200a
commit c34585cd72
+5
View File
@@ -391,6 +391,10 @@ class PythonWorkerPool:
try: try:
worker.send({**payload, "id": request_id}) worker.send({**payload, "id": request_id})
except OSError as exc: except OSError as exc:
# A broken pipe is the truthful signal here: poll() still reports a
# child that has exited but not yet been reaped as alive, so
# _release would hand this corpse to the next call. Retire it.
worker.cancelled = True
raise RemoteError(f"worker died: {exc}") from exc raise RemoteError(f"worker died: {exc}") from exc
while True: while True:
@@ -433,6 +437,7 @@ class PythonWorkerPool:
if line is None: if line is None:
worker.kill() worker.kill()
raise NodeTimeout(f"was silent for {timeout}s and was killed") raise NodeTimeout(f"was silent for {timeout}s and was killed")
worker.cancelled = True
raise RemoteError("worker died") raise RemoteError("worker died")
def compile( def compile(