From 646671a89fc8fcbe55b1ab952579446240503429 Mon Sep 17 00:00:00 2001 From: Qubasa Date: Tue, 19 Dec 2023 16:44:26 +0100 Subject: [PATCH] Fully working executor --- pkgs/clan-vm-manager/clan_vm_manager/app.py | 24 +++-------- .../clan_vm_manager/executor.py | 42 ++++++++++++------- 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/pkgs/clan-vm-manager/clan_vm_manager/app.py b/pkgs/clan-vm-manager/clan_vm_manager/app.py index 22a8a86b7..63f1e65dd 100644 --- a/pkgs/clan-vm-manager/clan_vm_manager/app.py +++ b/pkgs/clan-vm-manager/clan_vm_manager/app.py @@ -106,10 +106,11 @@ def register_overview_parser(parser: argparse.ArgumentParser) -> None: # Define a function that writes to the memfd -def dummy_f() -> None: +def dummy_f(msg: str) -> None: import sys import time + print(f"Receeived message {msg}") c = 0 while True: # Simulate a long running process print(f"out: Hello from process c={c}", file=sys.stdout) @@ -124,27 +125,12 @@ def dummy_f() -> None: def show_run_vm(parser: argparse.ArgumentParser) -> None: - import os - from .executor import spawn - print("Spawn process") - # proc = spawn(vms.run.run_vm, vm=vm) - proc = spawn(wait_stdin_connect=True, func=dummy_f) - - pid = os.getpid() - gpid = os.getpgid(pid) - print(f"Main pid={pid} gpid={gpid}") - assert proc.proc.pid is not None - gpid = os.getpgid(proc.proc.pid) - print(f"Child pid={proc.proc.pid} gpid={gpid}") + proc = spawn(wait_stdin_connect=True, func=dummy_f, msg="Hello") + input("Press enter to kill process: ") + proc.kill_group() def register_run_parser(parser: argparse.ArgumentParser) -> None: - # parser.add_argument( - # "command", - # type=str, - # help="command to run", - # choices=["join", "overview"], - # ) parser.set_defaults(func=show_run_vm) diff --git a/pkgs/clan-vm-manager/clan_vm_manager/executor.py b/pkgs/clan-vm-manager/clan_vm_manager/executor.py index 3f18ec16d..a0f181a22 100644 --- a/pkgs/clan-vm-manager/clan_vm_manager/executor.py +++ b/pkgs/clan-vm-manager/clan_vm_manager/executor.py @@ -21,21 +21,22 @@ class MPProcess: self.out_file_name = out_file_name self.in_file_name = in_file_name - def kill_all(self) -> None: + # Kill the new process and all its children by sending a SIGTERM signal to the process group + def kill_group(self) -> None: pid = self.proc.pid assert pid is not None + os.killpg(pid, signal.SIGTERM) - # Get the process group ID of the new process - new_pgid = os.getpgid(pid) - # Kill the new process and all its children by sending a SIGTERM signal to the process group - os.killpg(new_pgid, signal.SIGTERM) - # def get_all_output(self) -> str: - # os.lseek(self.out_fd, 0, os.SEEK_SET) - # return os.read(self.out_fd, 1024).decode("utf-8") - # def write_all_input(self, input_str: str) -> None: - # os.lseek(self.in_fd, 0, os.SEEK_SET) - # os.write(self.in_fd, input_str.encode("utf-8")) +def signal_handler(signum: int, frame: Any) -> None: + signame = signal.strsignal(signum) + print("Signal received:", signame) + + # Restore the default handler + signal.signal(signal.SIGTERM, signal.SIG_DFL) + + # Re-raise the signal + os.kill(os.getpid(), signum) def init_proc( @@ -47,6 +48,13 @@ def init_proc( os.dup2(out_fd, sys.stdout.fileno()) os.dup2(out_fd, sys.stderr.fileno()) + pid = os.getpid() + gpid = os.getpgid(pid=pid) + print(f"Started new process pid={pid} gpid={gpid}") + + # Register the signal handler for SIGINT + signal.signal(signal.SIGTERM, signal_handler) + flags = None if wait_stdin_connect: print(f"Waiting for stdin connection on file {in_file}", file=sys.stderr) @@ -70,11 +78,10 @@ def init_proc( def spawn(*, wait_stdin_connect: bool, func: Callable, **kwargs: Any) -> MPProcess: if mp.get_start_method(allow_none=True) is None: - print("Setting start method to spawn") mp.set_start_method(method="spawn") # rand_name = str(uuid.uuid4()) rand_name = "test" - proc_name = f"MPExecutor:{func.__name__}:{rand_name}" + proc_name = f"MPExecutor:{rand_name}:{func.__name__}" out_file_name = f"{rand_name}_out.txt" in_file_name = f"{rand_name}_in.fifo" @@ -90,8 +97,13 @@ def spawn(*, wait_stdin_connect: bool, func: Callable, **kwargs: Any) -> MPProce ) proc.start() assert proc.pid is not None - print(f"Started process '{proc_name}'. pid={proc.pid} gpid={os.getpgid(proc.pid)}") - + print(f"Started process '{proc_name}'") + print(f"Arguments: {kwargs}") + if wait_stdin_connect: + cmd = f"cat - > {in_file_name}" + print(f"Connect to stdin with : {cmd}") + cmd = f"tail -f {out_file_name}" + print(f"Connect to stdout with: {cmd}") mp_proc = MPProcess( name=proc_name, proc=proc,