import logging from quart_cors import cors from quart import Quart from app.core.bootstrap import AppContext from app.core.dependency import ServerContainer from app.api.v1.routes import server_routes from app.jobs.task_lifecycle import TaskLifecycleManager from app.core.observability import AlertService from app.infra.external import feishu_robot logging.basicConfig(level=logging.INFO) app = Quart(__name__) app = cors(app, allow_origin="*") app.config["ACCEPTING_TASKS"] = True server_container = ServerContainer() ctx = AppContext(server_container) config = server_container.config() log_service = server_container.log_service() mysql_manager = server_container.mysql_manager() routes = server_routes(mysql_manager, log_service, config) app.register_blueprint(routes) @app.before_serving async def startup(): logging.info("Starting application...") await ctx.start_up() # 初始化 AlertService alert_service = AlertService.initialize(feishu_robot) await alert_service.start() # 初始化 TaskLifecycleManager lifecycle = TaskLifecycleManager.initialize(mysql_manager, poll_interval=5.0) await lifecycle.start_polling() logging.info("Application started successfully") @app.after_serving async def shutdown(): logging.info("Shutting down application...") # 阶段 1:停止接收新任务 app.config["ACCEPTING_TASKS"] = False logging.info("Phase 1: Stopped accepting new tasks") # 阶段 2:取消/等待存量任务 lifecycle = TaskLifecycleManager.get_instance() if lifecycle: await lifecycle.shutdown(timeout=30.0) logging.info("Phase 2: All tasks cancelled/completed") # 阶段 3:flush 告警和日志 alert_service = AlertService.get_instance() if alert_service: await alert_service.stop(drain_timeout=5.0) await log_service.stop(drain_timeout=10.0) logging.info("Phase 3: Alerts and logs flushed") # 阶段 4:关闭数据库连接 await ctx.shutdown() logging.info("Phase 4: Database pools closed") logging.info("Application shutdown successfully")