Integrate scheduler service into FastAPI lifespan
- Start scheduler service during app startup - Gracefully stop scheduler during app shutdown - Track scheduler in initialized services - Scheduler starts after background loader - Scheduler shutdown with 5s timeout
This commit is contained in:
@@ -117,7 +117,8 @@ async def lifespan(_application: FastAPI):
|
|||||||
initialized = {
|
initialized = {
|
||||||
'database': False,
|
'database': False,
|
||||||
'services': False,
|
'services': False,
|
||||||
'background_loader': False
|
'background_loader': False,
|
||||||
|
'scheduler': False
|
||||||
}
|
}
|
||||||
|
|
||||||
# Startup
|
# Startup
|
||||||
@@ -265,6 +266,18 @@ async def lifespan(_application: FastAPI):
|
|||||||
initialized['background_loader'] = True
|
initialized['background_loader'] = True
|
||||||
logger.info("Background loader service started")
|
logger.info("Background loader service started")
|
||||||
|
|
||||||
|
# Initialize and start scheduler service
|
||||||
|
from src.server.services.scheduler_service import get_scheduler_service
|
||||||
|
|
||||||
|
scheduler_service = get_scheduler_service()
|
||||||
|
try:
|
||||||
|
await scheduler_service.start()
|
||||||
|
initialized['scheduler'] = True
|
||||||
|
logger.info("Scheduler service started")
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning("Failed to start scheduler service: %s", e)
|
||||||
|
# Continue - scheduler is optional
|
||||||
|
|
||||||
# Run media scan only on first run
|
# Run media scan only on first run
|
||||||
await perform_media_scan_if_needed(background_loader)
|
await perform_media_scan_if_needed(background_loader)
|
||||||
else:
|
else:
|
||||||
@@ -322,7 +335,23 @@ async def lifespan(_application: FastAPI):
|
|||||||
elapsed = time.monotonic() - shutdown_start
|
elapsed = time.monotonic() - shutdown_start
|
||||||
return max(0.0, SHUTDOWN_TIMEOUT - elapsed)
|
return max(0.0, SHUTDOWN_TIMEOUT - elapsed)
|
||||||
|
|
||||||
# 1. Stop background loader service (only if initialized)
|
# 1. Stop scheduler service (only if initialized)
|
||||||
|
if initialized['scheduler']:
|
||||||
|
try:
|
||||||
|
from src.server.services.scheduler_service import get_scheduler_service
|
||||||
|
scheduler_service = get_scheduler_service()
|
||||||
|
logger.info("Stopping scheduler service...")
|
||||||
|
await asyncio.wait_for(
|
||||||
|
scheduler_service.stop(),
|
||||||
|
timeout=min(5.0, remaining_time())
|
||||||
|
)
|
||||||
|
logger.info("Scheduler service stopped")
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
logger.warning("Scheduler service shutdown timed out")
|
||||||
|
except Exception as e: # pylint: disable=broad-exception-caught
|
||||||
|
logger.error("Error stopping scheduler service: %s", e, exc_info=True)
|
||||||
|
|
||||||
|
# 2. Stop background loader service (only if initialized)
|
||||||
if initialized['background_loader']:
|
if initialized['background_loader']:
|
||||||
try:
|
try:
|
||||||
from src.server.utils.dependencies import _background_loader_service
|
from src.server.utils.dependencies import _background_loader_service
|
||||||
@@ -338,7 +367,7 @@ async def lifespan(_application: FastAPI):
|
|||||||
except Exception as e: # pylint: disable=broad-exception-caught
|
except Exception as e: # pylint: disable=broad-exception-caught
|
||||||
logger.error("Error stopping background loader service: %s", e, exc_info=True)
|
logger.error("Error stopping background loader service: %s", e, exc_info=True)
|
||||||
|
|
||||||
# 2. Broadcast shutdown notification via WebSocket
|
# 3. Broadcast shutdown notification via WebSocket
|
||||||
try:
|
try:
|
||||||
ws_service = get_websocket_service()
|
ws_service = get_websocket_service()
|
||||||
logger.info("Broadcasting shutdown notification to WebSocket clients...")
|
logger.info("Broadcasting shutdown notification to WebSocket clients...")
|
||||||
@@ -352,7 +381,7 @@ async def lifespan(_application: FastAPI):
|
|||||||
except Exception as e: # pylint: disable=broad-exception-caught
|
except Exception as e: # pylint: disable=broad-exception-caught
|
||||||
logger.error("Error during WebSocket shutdown: %s", e, exc_info=True)
|
logger.error("Error during WebSocket shutdown: %s", e, exc_info=True)
|
||||||
|
|
||||||
# 3. Shutdown download service and persist active downloads
|
# 4. Shutdown download service and persist active downloads
|
||||||
try:
|
try:
|
||||||
from src.server.services.download_service import ( # noqa: E501
|
from src.server.services.download_service import ( # noqa: E501
|
||||||
_download_service_instance,
|
_download_service_instance,
|
||||||
|
|||||||
Reference in New Issue
Block a user