#!/usr/bin/env python3 # -*- coding: utf-8 -*- import logging import asyncio import signal import sys from typing import List, Callable from enum import Enum logger = logging.getLogger(__name__) class ShutdownPriority(Enum): """关闭优先级枚举""" HIGHEST = 0 HIGH = 1 NORMAL = 2 LOW = 3 LOWEST = 4 class ShutdownService: """关闭服务 - 管理框架的优雅关闭""" def __init__(self, service_manager): self.service_manager = service_manager self.shutdown_handlers: List[Callable] = [] self.is_shutting_down = False self.shutdown_timeout = 30 # 秒 logger.debug("ShutdownService初始化开始") # 注册信号处理 self._register_signal_handlers() def _register_signal_handlers(self): """注册信号处理""" try: signal.signal(signal.SIGINT, self._signal_handler) signal.signal(signal.SIGTERM, self._signal_handler) logger.debug("信号处理器注册完成") except Exception as e: logger.error(f"注册信号处理器时出错: {str(e)}", exc_info=True) def _signal_handler(self, signum, frame): """信号处理函数""" try: signal_name = signal.Signals(signum).name logger.info(f"接收到信号: {signal_name}") asyncio.create_task(self.initiate_shutdown()) except Exception as e: logger.error(f"处理信号时出错: {str(e)}", exc_info=True) sys.exit(1) def register_shutdown_handler(self, handler: Callable, priority: ShutdownPriority = ShutdownPriority.NORMAL): """注册关闭处理器""" try: self.shutdown_handlers.append((priority.value, handler)) # 按优先级排序 self.shutdown_handlers.sort(key=lambda x: x[0]) logger.debug(f"注册关闭处理器,优先级: {priority.name}, 当前总数: {len(self.shutdown_handlers)}") except Exception as e: logger.error(f"注册关闭处理器时出错: {str(e)}", exc_info=True) async def initiate_shutdown(self, reason: str = "正常关闭"): """发起关闭流程""" try: if self.is_shutting_down: logger.warning("关闭流程已在进行中") return self.is_shutting_down = True logger.info(f"开始框架关闭流程 - 原因: {reason}") # 执行关闭处理器 await self._execute_shutdown_handlers() # 关闭服务管理器 self.service_manager.shutdown_all() logger.info("框架关闭完成") # 退出程序 sys.exit(0) except Exception as e: logger.error(f"关闭流程出错: {str(e)}", exc_info=True) sys.exit(1) async def _execute_shutdown_handlers(self): """执行关闭处理器""" try: logger.debug(f"开始执行 {len(self.shutdown_handlers)} 个关闭处理器") for priority, handler in self.shutdown_handlers: try: handler_name = handler.__name__ if hasattr(handler, '__name__') else str(handler) logger.debug(f"执行关闭处理器: {handler_name} (优先级: {priority})") if asyncio.iscoroutinefunction(handler): await asyncio.wait_for(handler(), timeout=self.shutdown_timeout) else: # 在事件循环中运行同步函数 await asyncio.get_event_loop().run_in_executor(None, handler) logger.debug(f"关闭处理器完成: {handler_name}") except asyncio.TimeoutError: logger.error(f"关闭处理器超时: {handler_name}") except Exception as e: logger.error(f"关闭处理器出错 {handler_name}: {str(e)}", exc_info=True) logger.debug("所有关闭处理器执行完成") except Exception as e: logger.error(f"执行关闭处理器时出错: {str(e)}", exc_info=True) def emergency_shutdown(self): """紧急关闭""" try: logger.critical("执行紧急关闭") sys.exit(1) except Exception as e: logger.critical(f"紧急关闭时出错: {str(e)}") os._exit(1) def shutdown(self): """关闭关闭服务""" try: logger.info("关闭ShutdownService") self.shutdown_handlers.clear() logger.debug("ShutdownService关闭完成") except Exception as e: logger.error(f"关闭ShutdownService时出错: {str(e)}", exc_info=True)