import asyncio import os from contextlib import asynccontextmanager from fastapi import FastAPI from services.device_config import DeviceConfigManager from services.schedule_session_cleanup import background_cleanup_task from services.role_manager import role_manager from services.task_manager import task_manager from initialization import register_services, init_directories from config import settings from utils.logger import session_logger from api import api_router from api.assets import configure_static_assets from database.init_db import init_db from database.connection import get_db_manager from services.firmware_scanner import firmware_scanner device_config_manager = DeviceConfigManager() @asynccontextmanager async def lifespan(app: FastAPI): worker_id = os.environ.get("UVICORN_WID", "0") is_main_process = worker_id == "0" if is_main_process: session_logger.system_info( "startup", f"服务器启动,HTTP服务地址: http://{settings.server_host}:{settings.server_port}", ) init_directories() try: session_logger.system_info("startup", "初始化数据库...") await init_db() session_logger.system_info("startup", "数据库初始化和迁移完成") except Exception as e: session_logger.system_info("startup", f"数据库初始化失败: {str(e)}") await role_manager.initialize() await register_services() try: await firmware_scanner.scan_firmware_files() session_logger.system_info("startup", "固件文件扫描完成") except Exception as e: session_logger.system_info("startup", f"固件文件扫描失败: {str(e)}") session_logger.system_info("startup", "中断处理服务已初始化") cleanup_task = asyncio.create_task(background_cleanup_task()) try: yield finally: cleanup_task.cancel() try: await asyncio.wait_for(cleanup_task, timeout=5.0) except (asyncio.CancelledError, asyncio.TimeoutError): if is_main_process: session_logger.system_info("shutdown", "后台清理任务已取消") from services.audio_session import audio_session_manager sessions_to_close = [] async for session_key, session in audio_session_manager.get_all_sessions(): sessions_to_close.append((session_key, session)) for session_key, session in sessions_to_close: try: if session.send_task: session.send_task.cancel() if hasattr(session, "asr_service") and session.asr_service: await session.asr_service.close() if hasattr(session, "llm_service") and session.llm_service: await session.llm_service.close() except Exception as e: if is_main_process: session_logger.system_info("shutdown", f"清理会话时出错: {str(e)}") # 清理所有任务管理器的任务 try: await task_manager.cleanup_all_tasks() if is_main_process: session_logger.system_info("shutdown", "任务管理器清理完成") except Exception as e: if is_main_process: session_logger.system_info("shutdown", f"任务管理器清理时出错: {str(e)}") try: db_manager = await get_db_manager() await db_manager.close() if is_main_process: session_logger.system_info("shutdown", "数据库连接已关闭") except Exception as e: if is_main_process: session_logger.system_info("shutdown", f"关闭数据库连接时出错: {str(e)}") if is_main_process: session_logger.system_info("shutdown", "应用关闭") app = FastAPI(lifespan=lifespan) configure_static_assets(app) app.include_router(api_router)