""" PyServe Daemon Process Runs pyserve services in background mode. """ import argparse import asyncio import logging import os import signal import sys from pathlib import Path def main(): parser = argparse.ArgumentParser(description="PyServe Daemon") parser.add_argument("--config", required=True, help="Configuration file path") parser.add_argument("--state-dir", required=True, help="State directory path") parser.add_argument("--services", default=None, help="Comma-separated list of services") parser.add_argument("--scale", action="append", default=[], help="Scale overrides (name=workers)") parser.add_argument("--force-recreate", action="store_true", help="Force recreate services") args = parser.parse_args() config_path = Path(args.config) state_dir = Path(args.state_dir) services = args.services.split(",") if args.services else None scale_map = {} for scale in args.scale: name, workers = scale.split("=") scale_map[name] = int(workers) from ..config import Config config = Config.from_yaml(str(config_path)) from .state import StateManager state_manager = StateManager(state_dir) log_file = state_dir / "logs" / "daemon.log" log_file.parent.mkdir(parents=True, exist_ok=True) logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", handlers=[ logging.FileHandler(log_file), ], ) logger = logging.getLogger("pyserve.daemon") pid_file = state_dir / "pyserve.pid" pid_file.write_text(str(os.getpid())) logger.info(f"Starting daemon with PID {os.getpid()}") from ._runner import ServiceRunner runner = ServiceRunner(config, state_manager) def signal_handler(signum, frame): logger.info(f"Received signal {signum}, shutting down...") runner.stop() signal.signal(signal.SIGTERM, signal_handler) signal.signal(signal.SIGINT, signal_handler) try: asyncio.run( runner.start( services=services, scale_map=scale_map, force_recreate=args.force_recreate, ) ) except Exception as e: logger.error(f"Daemon error: {e}") sys.exit(1) finally: if pid_file.exists(): pid_file.unlink() logger.info("Daemon stopped") if __name__ == "__main__": main()