Minecraft-Friends-AI-ZeroGPU / voyager_processes.py
Erinaldordso's picture
Repair Voyager deadlines and connect both bots to Mine
b31ff59 verified
Raw History Blame Contribute Delete
1.68 kB
"""Stop one isolated runner session, including orphaned Mineflayer children."""
from __future__ import annotations
import os
import signal
import subprocess
import psutil
def stop_runner(proc: subprocess.Popen | None, timeout: float = 10) -> None:
"""Only pass children launched with start_new_session=True on POSIX."""
if proc is None:
return
members = []
if os.name == "posix":
for child in psutil.process_iter(["pid"]):
try:
if os.getpgid(child.pid) == proc.pid:
members.append(child)
except (ProcessLookupError, PermissionError):
pass
try:
os.killpg(proc.pid, signal.SIGTERM)
except ProcessLookupError:
return
elif proc.poll() is None:
proc.terminate()
try:
proc.wait(timeout=timeout)
except subprocess.TimeoutExpired:
if os.name != "posix":
proc.kill()
finally:
# The session leader may have exited through os._exit(75), leaving its
# Node child holding port 3000/3001. Its group still belongs to this
# runner, even when proc.poll() reports an exit.
if os.name == "posix":
try:
os.killpg(proc.pid, signal.SIGKILL)
except ProcessLookupError:
pass
# Sending a signal is asynchronous. Wait for those exact session
# members so the next runner cannot race their socket cleanup.
psutil.wait_procs(members, timeout=2)
try:
proc.wait(timeout=5)
except subprocess.TimeoutExpired:
pass