61 lines
1.6 KiB
Python
61 lines
1.6 KiB
Python
import os
|
|
import asyncio
|
|
import multiprocessing as mp
|
|
from fastapi import APIRouter
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("/info")
|
|
async def get_system_info():
|
|
"""Return system info: CPU cores, GPU availability, parallel backend."""
|
|
cpu_cores = mp.cpu_count() or 1
|
|
|
|
# Check Ray
|
|
ray_available = False
|
|
ray_initialized = False
|
|
try:
|
|
from app.services.parallel_coverage_service import RAY_AVAILABLE
|
|
ray_available = RAY_AVAILABLE
|
|
if ray_available:
|
|
import ray
|
|
ray_initialized = ray.is_initialized()
|
|
except Exception:
|
|
pass
|
|
|
|
# Check GPU via gpu_service
|
|
from app.services.gpu_service import gpu_service
|
|
gpu_info = gpu_service.get_info()
|
|
|
|
# Determine parallel backend
|
|
if ray_available:
|
|
parallel_backend = "ray"
|
|
elif cpu_cores > 1:
|
|
parallel_backend = "process_pool"
|
|
else:
|
|
parallel_backend = "sequential"
|
|
|
|
return {
|
|
"cpu_cores": cpu_cores,
|
|
"parallel_workers": min(cpu_cores, 14),
|
|
"parallel_backend": parallel_backend,
|
|
"ray_available": ray_available,
|
|
"ray_initialized": ray_initialized,
|
|
"gpu": gpu_info,
|
|
"gpu_available": gpu_info.get("available", False),
|
|
}
|
|
|
|
|
|
@router.post("/shutdown")
|
|
async def shutdown():
|
|
"""Graceful shutdown endpoint. Kills worker processes and exits."""
|
|
from app.services.parallel_coverage_service import _kill_worker_processes
|
|
|
|
killed = _kill_worker_processes()
|
|
|
|
# Schedule hard exit after response is sent
|
|
loop = asyncio.get_event_loop()
|
|
loop.call_later(0.5, lambda: os._exit(0))
|
|
|
|
return {"status": "shutting down", "workers_killed": killed}
|