TestTranslator / lib /app_runner.py
yujuanqin's picture
fix app not running
ef9c2a5
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()