2025-02-26 10:42:11 +01:00
|
|
|
import logging
|
2025-02-17 15:58:53 +01:00
|
|
|
import signal
|
|
|
|
import subprocess
|
|
|
|
import sys
|
2025-02-26 14:37:22 +01:00
|
|
|
from pathlib import Path
|
2025-02-17 15:58:53 +01:00
|
|
|
|
|
|
|
import psutil
|
|
|
|
|
2025-02-26 10:42:11 +01:00
|
|
|
from sith import settings
|
|
|
|
|
|
|
|
|
|
|
|
def get_pid() -> int | None:
|
|
|
|
"""Read the PID file to get the currently running composer if it exists"""
|
|
|
|
if not settings.COMPOSER_PID_PATH.exists():
|
|
|
|
return None
|
|
|
|
with open(settings.COMPOSER_PID_PATH, "r", encoding="utf8") as f:
|
|
|
|
return int(f.read())
|
|
|
|
|
|
|
|
|
|
|
|
def write_pid(pid: int):
|
|
|
|
"""Write currently running composer pid in PID file"""
|
|
|
|
if not settings.COMPOSER_PID_PATH.exists():
|
|
|
|
settings.COMPOSER_PID_PATH.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
with open(settings.COMPOSER_PID_PATH, "w", encoding="utf8") as f:
|
|
|
|
_ = f.write(str(pid))
|
|
|
|
|
|
|
|
|
|
|
|
def delete_pid():
|
|
|
|
"""Delete PID file for cleanup"""
|
|
|
|
settings.COMPOSER_PID_PATH.unlink(missing_ok=True)
|
|
|
|
|
|
|
|
|
|
|
|
def is_composer_running() -> bool:
|
|
|
|
"""Check if the process in the PID file is running"""
|
|
|
|
pid = get_pid()
|
|
|
|
if pid is None:
|
|
|
|
return False
|
|
|
|
try:
|
|
|
|
return psutil.Process(pid).is_running()
|
|
|
|
except psutil.NoSuchProcess:
|
|
|
|
return False
|
2025-02-17 15:58:53 +01:00
|
|
|
|
|
|
|
|
2025-02-26 14:37:22 +01:00
|
|
|
def start_composer(procfile: Path):
|
2025-02-17 15:58:53 +01:00
|
|
|
"""Starts the composer and stores the PID as an environment variable
|
|
|
|
This allows for running smoothly with the django reloader
|
|
|
|
"""
|
2025-02-26 10:42:11 +01:00
|
|
|
if is_composer_running():
|
|
|
|
logging.info(f"Composer is already running with pid {get_pid()}")
|
|
|
|
logging.info(
|
|
|
|
f"If this is a mistake, please delete {settings.COMPOSER_PID_PATH} and restart the process"
|
|
|
|
)
|
|
|
|
return
|
2025-02-17 15:58:53 +01:00
|
|
|
process = subprocess.Popen(
|
2025-02-26 14:37:22 +01:00
|
|
|
[sys.executable, "-m", "honcho", "-f", str(procfile), "start"],
|
2025-02-17 15:58:53 +01:00
|
|
|
)
|
2025-02-26 10:42:11 +01:00
|
|
|
write_pid(process.pid)
|
2025-02-17 15:58:53 +01:00
|
|
|
|
|
|
|
|
|
|
|
def stop_composer():
|
|
|
|
"""Stops the composer if it was started before"""
|
2025-02-26 10:42:11 +01:00
|
|
|
if is_composer_running():
|
|
|
|
process = psutil.Process(get_pid())
|
|
|
|
if process.parent() != psutil.Process():
|
|
|
|
logging.info("Currently running composer is controlled by another process")
|
|
|
|
return
|
2025-02-17 15:58:53 +01:00
|
|
|
process.send_signal(signal.SIGTERM)
|
2025-02-26 10:42:11 +01:00
|
|
|
_ = process.wait()
|
|
|
|
delete_pid()
|