fix: 完善服务重启交互

This commit is contained in:
2026-05-18 17:34:23 +08:00
parent d91d2f91fa
commit 3750160891
6 changed files with 201 additions and 36 deletions
+25 -27
View File
@@ -1,13 +1,14 @@
import os
import platform
import subprocess
import time
from threading import Thread
from fastapi import APIRouter
from app.services.runtime import (
is_container_runtime,
is_supervisor_running,
restart_method_name,
restart_via_supervisor,
terminate_current_process,
)
@@ -18,38 +19,35 @@ router = APIRouter(tags=["service"])
@router.post("/api/service/restart")
async def restart_service():
if is_supervisor_running():
supervisor_running = is_supervisor_running()
container_runtime = is_container_runtime()
if supervisor_running:
success, message = restart_via_supervisor()
return {"success": success, "message": message, "method": "supervisor"}
if platform.system() != "Windows":
try:
result = subprocess.run(
["supervisorctl", "restart", "fastapi"],
capture_output=True,
text=True,
timeout=30,
)
if result.returncode == 0:
return {
"success": True,
"message": "服务正在通过 supervisor 重启...",
"method": "supervisor",
}
except FileNotFoundError:
pass
except subprocess.TimeoutExpired:
if success:
return {
"success": False,
"message": "重启操作超时,请检查 supervisor 状态",
"success": True,
"message": message,
"method": "supervisor",
"container": container_runtime,
}
except Exception:
pass
method = restart_method_name(supervisor_running)
thread = Thread(target=_delayed_exit, daemon=True)
thread.start()
return {"success": True, "message": "服务正在重启,请稍后刷新页面...", "method": "signal"}
message = "服务正在重启,请稍后刷新页面..."
if supervisor_running:
message = "supervisor 命令不可用,已切换为进程重启..."
elif container_runtime:
message = "服务进程正在退出,容器或进程管理器将拉起服务..."
return {
"success": True,
"message": message,
"method": method,
"container": container_runtime,
}
@router.get("/api/service/status")
@@ -59,6 +57,7 @@ async def get_service_status():
"version": "2.0.2",
"platform": platform.system(),
"supervisor": is_supervisor_running(),
"container": is_container_runtime(),
"pid": os.getpid(),
"python_version": platform.python_version(),
}
@@ -67,4 +66,3 @@ async def get_service_status():
def _delayed_exit() -> None:
time.sleep(1)
terminate_current_process()
+28 -1
View File
@@ -25,6 +25,24 @@ def is_supervisor_running() -> bool:
return _command_succeeds(["pgrep", "-f", "supervisord"], timeout=2)
def is_container_runtime() -> bool:
if os.environ.get("container"):
return True
if Path("/.dockerenv").exists():
return True
cgroup_path = Path("/proc/1/cgroup")
if not cgroup_path.exists():
return False
try:
cgroup = cgroup_path.read_text(encoding="utf-8", errors="ignore").lower()
except Exception:
return False
return any(marker in cgroup for marker in ("docker", "kubepods", "containerd"))
def restart_via_supervisor() -> tuple[bool, str]:
try:
result = subprocess.run(
@@ -52,10 +70,19 @@ def terminate_current_process() -> None:
os.kill(os.getpid(), signal.SIGTERM)
def restart_method_name(supervisor_running: bool) -> str:
if supervisor_running:
return "supervisor"
if platform.system() == "Windows":
return "windows-process"
if is_container_runtime():
return "container-process"
return "process"
def _command_succeeds(command: list[str], timeout: int) -> bool:
try:
result = subprocess.run(command, capture_output=True, text=True, timeout=timeout)
return result.returncode == 0 and bool(result.stdout.strip() or command[0] == "supervisorctl")
except Exception:
return False