File size: 2,821 Bytes
ade4f6a 6b3e951 ade4f6a cbe0c62 ade4f6a c95b373 ade4f6a ef9c2a5 c95b373 ade4f6a ef9c2a5 ade4f6a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
import signal
from typing import Literal
import subprocess
import time
import threading
import os
import signal
from environment import *
class AppRunner:
def __init__(self, run_type: RunType):
self.run_type = run_type
self.sub_proc = None
def start(self):
print(f"start app by type: {self.run_type}")
if self.run_type==RunType.electron:
cmd_args = [APP_PATH, f"--remote-debugging-port={DEBUG_PORT}"]
cwd = None
log_file = APP_LOG
elif self.run_type == RunType.code:
cmd_args = ["python", str(CODE_PATH)]
cwd = CODE_DIR
log_file = CODE_LOG
elif self.run_type == RunType.dev:
cmd_args = ["python", str(DEV_PATH)]
cwd = DEV_DIR
log_file = DEV_LOG
else:
raise TypeError(f"invalid run_type: {self.run_type}")
self.clear_log(log_file)
self.sub_proc = subprocess.Popen(
cmd_args,
cwd=cwd,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
preexec_fn= os.setsid
)
print(f"translator started, PID: {self.sub_proc.pid}")
time.sleep(10) # 等待app 启动
self.wait_for_app_start(log_file)
print(f"translator is ready.")
return self.sub_proc
def clear_log(self, log_path: Path):
if log_path.exists():
log_path.unlink(missing_ok=True)
def wait_for_app_start(self, log_file, timeout = 60, interval=3):
for i in range(int(timeout/interval)):
ret = subprocess.run(f"tail -n 10 {log_file}", check=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
universal_newlines=True)
if "Pipeline is ready" in ret.stdout:
return True
# print(ret.stdout)
print(f"app is not started yet, retry {i+1}...")
time.sleep(interval)
print(ret.stdout)
self.stop()
raise RuntimeError(f"app not started in {timeout}s")
def stop(self):
pgid = os.getpgid(self.sub_proc.pid)
os.killpg(pgid, signal.SIGTERM)
try:
time.sleep(3)
return_code = self.sub_proc.wait(timeout=10)
print(f"进程组已终止,进程退出码: {return_code}")
except subprocess.TimeoutExpired:
print("超时,进程组可能未完全终止,尝试 SIGKILL...")
os.killpg(pgid, signal.SIGKILL)
self.sub_proc.wait(timeout=10)
print("进程组已被强制杀死。")
except Exception as e:
print("停止进程失败:", e)
if __name__ == '__main__':
app = AppRunner(RunType.code)
app.start()
print(app.wait_for_app_start())
app.stop() |