"""应用生命周期管理""" import asyncio from contextlib import asynccontextmanager from fastapi import FastAPI from app.core.db import init_db, get_db from app.core.config import settings as app_settings from app.core.log import logger from app.api.deps import create_scheduler_service from app.repositories.settings_repo import SettingsRepository, DEFAULT_SETTINGS settings_repo = SettingsRepository() @asynccontextmanager async def lifespan(app: FastAPI): """应用启动和关闭时的生命周期管理""" # 初始化数据库 await init_db() # 加载设置并决定是否启动调度器 db_settings = DEFAULT_SETTINGS.copy() try: async with get_db() as db: db_settings = await settings_repo.get_all(db) except Exception as e: logger.error(f"Failed to load settings on startup: {e}") # 创建调度器并挂载到 app.state(使用 DB 设置覆盖默认值) scheduler_service = create_scheduler_service(db_settings) app.state.scheduler_service = scheduler_service app.state.validation_queue = scheduler_service.validation_queue if db_settings.get("auto_validate", True): try: await scheduler_service.start() except Exception as e: logger.error(f"Failed to start scheduler on startup: {e}") logger.info("API server started") yield # 关闭调度器 scheduler_service.cancel_validate_task() await scheduler_service.stop() # 关闭验证器 HTTP session try: await scheduler_service.validation_queue.validator.close() except Exception: pass # 关闭所有插件的 HTTP 客户端 from app.core.plugin_system.registry import registry for plugin in registry.list_plugins(): if hasattr(plugin, "close"): try: await plugin.close() except Exception: pass # 给 aiosqlite / aiohttp 后台线程留出收尾时间 await asyncio.sleep(0.1) logger.info("API server shutdown")