pyservectl init
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
"""
|
||||
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__":
|
||||
import os
|
||||
|
||||
main()
|
||||
Reference in New Issue
Block a user