Files
video_upscaler/stop.py
T

98 lines
2.8 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
stop.py — Stop the AI Video Upscaler web application.
Usage:
python stop.py
"""
import os
import signal
import sys
import time
# ── Paths ────────────────────────────────────────────────────────────────────
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
PID_FILE = os.path.join(BASE_DIR, ".uvicorn.pid")
def _is_running(pid: int) -> bool:
"""Check whether a process with the given PID is still alive and is our server."""
try:
os.kill(pid, 0)
except OSError:
return False
# Check /proc/{pid}/cmdline to verify it's our server process
try:
cmdline_path = f"/proc/{pid}/cmdline"
if os.path.exists(cmdline_path):
with open(cmdline_path, "r") as f:
cmdline = f.read()
# Check for indicators of our server
return "uvicorn" in cmdline or "app.main" in cmdline
except Exception:
pass
# If we can't read cmdline, default to True (safer fallback)
return True
def stop() -> None:
if not os.path.isfile(PID_FILE):
print("ℹ No server appears to be running (no pidfile found).")
return
try:
pid = int(open(PID_FILE).read().strip())
except (ValueError, OSError):
print("⚠ Pidfile exists but is unreadable. Removing it.")
os.remove(PID_FILE)
return
if not _is_running(pid):
print(f"ℹ Server (PID {pid}) is not running. Cleaning up pidfile.")
os.remove(PID_FILE)
return
print(f"🛑 Stopping server (PID {pid}) …")
# Clean up child processes of the server and any lingering upscaler binaries
import subprocess
try:
subprocess.run(["pkill", "-P", str(pid)], capture_output=True)
except Exception:
pass
try:
subprocess.run(["pkill", "-f", "realesrgan-ncnn-vulkan"], capture_output=True)
subprocess.run(["pkill", "-f", "rife-ncnn-vulkan"], capture_output=True)
except Exception:
pass
# Graceful shutdown (SIGTERM)
os.kill(pid, signal.SIGTERM)
# Wait up to 10 seconds for graceful exit
for i in range(20):
time.sleep(0.5)
if not _is_running(pid):
break
else:
# Force kill if still alive
print(f" ⚠ Server didn't stop gracefully, sending SIGKILL …")
os.kill(pid, signal.SIGKILL)
time.sleep(0.5)
# Clean up pidfile
if os.path.isfile(PID_FILE):
os.remove(PID_FILE)
if _is_running(pid):
print(f"❌ Failed to stop server (PID {pid}).")
sys.exit(1)
else:
print(f"✅ Server stopped.")
if __name__ == "__main__":
stop()