fix(process): reap children after early stdout EOF

This commit is contained in:
fangliquan
2026-09-14 22:13:04 +08:00
committed by Teknium
parent 8bc5894a3a
commit 1bfbeff4e5
2 changed files with 60 additions and 3 deletions
+9 -3
View File
@@ -1161,11 +1161,16 @@ class ProcessRegistry(ProcessCheckpointMixin):
finally:
self._finish_reader(
session, decoder, _append_chunk, "Process",
lambda: session.process.wait(timeout=5), lambda: session.process.returncode)
session.process.wait, lambda: session.process.returncode)
def _finish_reader(self, session, decoder, append, label, wait, exit_code) -> None:
"""Reader-thread teardown: flush the decoder (a truncated multibyte tail becomes
one U+FFFD instead of vanishing), reap the child (no zombies), record the exit."""
one U+FFFD instead of vanishing), reap the child (no zombies), record the exit.
A process may close stdout long before it exits. The reader owns a dedicated
daemon thread, so it must keep waiting rather than publish a false completion
and discard the only ``Popen`` handle that can reap the child.
"""
with suppress(Exception):
tail = decoder.decode(b"", final=True)
if tail:
@@ -1173,7 +1178,8 @@ class ProcessRegistry(ProcessCheckpointMixin):
try:
wait()
except Exception as e:
logger.debug("%s wait timed out or failed: %s", label, e)
logger.warning("%s wait failed; leaving process tracked: %s", label, e)
return
self._finish_exited(session, exit_code())
@staticmethod