diff --git a/bot.py b/bot.py index cde011249..4d5e12a49 100644 --- a/bot.py +++ b/bot.py @@ -76,7 +76,7 @@ async def request_shutdown() -> bool: try: if loop and not loop.is_closed(): try: - loop.run_until_complete(graceful_shutdown()) + loop.run_until_complete(graceful_shutdown(maibot.main_system)) except Exception as ge: # 捕捉优雅关闭时可能发生的错误 logger.error(f"优雅关闭时发生错误: {ge}") return False @@ -97,18 +97,15 @@ def easter_egg(): logger.info(rainbow_text) -async def graceful_shutdown(): +async def graceful_shutdown(main_system_instance): + """优雅地关闭所有系统组件""" try: logger.info("正在优雅关闭麦麦...") - # 首先停止服务器组件,避免网络连接被强制关闭 - try: - global server - if server and hasattr(server, 'shutdown'): - logger.info("正在关闭服务器...") - await server.shutdown() - except Exception as e: - logger.warning(f"关闭服务器时出错: {e}") + # 停止MainSystem中的组件,它会处理服务器等 + if main_system_instance and hasattr(main_system_instance, 'shutdown'): + logger.info("正在关闭MainSystem...") + await main_system_instance.shutdown() # 停止聊天管理器 try: @@ -138,14 +135,6 @@ async def graceful_shutdown(): except Exception as e: logger.warning(f"停止记忆系统时出错: {e}") - # 停止MainSystem - try: - global main_system - if main_system and hasattr(main_system, 'shutdown'): - logger.info("正在停止MainSystem...") - await main_system.shutdown() - except Exception as e: - logger.warning(f"停止MainSystem时出错: {e}") # 停止所有异步任务 try: @@ -178,6 +167,15 @@ async def graceful_shutdown(): # 关闭日志系统,释放文件句柄 shutdown_logging() + # 尝试停止事件循环 + try: + loop = asyncio.get_running_loop() + if loop.is_running(): + loop.stop() + logger.info("事件循环已请求停止") + except RuntimeError: + pass # 没有正在运行的事件循环 + except Exception as e: logger.error(f"麦麦关闭失败: {e}", exc_info=True) @@ -305,18 +303,13 @@ if __name__ == "__main__": if "loop" in locals() and loop and not loop.is_closed(): logger.info("开始执行最终关闭流程...") try: - loop.run_until_complete(graceful_shutdown()) + # 传递main_system实例 + loop.run_until_complete(graceful_shutdown(maibot.main_system)) except Exception as ge: logger.error(f"优雅关闭时发生错误: {ge}") loop.close() logger.info("事件循环已关闭") - # 关闭日志系统,释放文件句柄 - try: - shutdown_logging() - except Exception as e: - print(f"关闭日志系统时出错: {e}") - # 在程序退出前暂停,让你有机会看到输出 # input("按 Enter 键退出...") # <--- 添加这行 sys.exit(exit_code) # <--- 使用记录的退出码 diff --git a/src/chat/emoji_system/emoji_manager.py b/src/chat/emoji_system/emoji_manager.py index 62552a201..0d7d71a7c 100644 --- a/src/chat/emoji_system/emoji_manager.py +++ b/src/chat/emoji_system/emoji_manager.py @@ -402,6 +402,12 @@ class EmojiManager: logger.info("启动表情包管理器") + def shutdown(self) -> None: + """关闭EmojiManager,取消正在运行的任务""" + if self._scan_task and not self._scan_task.done(): + self._scan_task.cancel() + logger.info("表情包扫描任务已取消") + def initialize(self) -> None: """初始化数据库连接和表情目录""" diff --git a/src/chat/memory_system/memory_system.py b/src/chat/memory_system/memory_system.py index fc802c5d2..977c130b8 100644 --- a/src/chat/memory_system/memory_system.py +++ b/src/chat/memory_system/memory_system.py @@ -1425,16 +1425,6 @@ class MemorySystem: def _fingerprint_key(user_id: str, fingerprint: str) -> str: return f"{user_id!s}:{fingerprint}" - def get_system_stats(self) -> dict[str, Any]: - """获取系统统计信息""" - return { - "status": self.status.value, - "total_memories": self.total_memories, - "last_build_time": self.last_build_time, - "last_retrieval_time": self.last_retrieval_time, - "config": asdict(self.config), - } - def _compute_memory_score(self, query_text: str, memory: MemoryChunk, context: dict[str, Any]) -> float: """根据查询和上下文为记忆计算匹配分数""" tokens_query = self._tokenize_text(query_text) @@ -1542,7 +1532,7 @@ class MemorySystem: # 保存统一存储数据 if self.unified_storage: - await self.unified_storage.cleanup() + self.unified_storage.cleanup() logger.info("✅ 简化记忆系统已关闭") diff --git a/src/chat/memory_system/vector_memory_storage_v2.py b/src/chat/memory_system/vector_memory_storage_v2.py index 5c349b584..fd5ca144f 100644 --- a/src/chat/memory_system/vector_memory_storage_v2.py +++ b/src/chat/memory_system/vector_memory_storage_v2.py @@ -964,6 +964,11 @@ class VectorMemoryStorage: logger.info("Vector记忆存储系统已停止") + def cleanup(self): + """清理资源,兼容旧接口""" + logger.info("正在清理VectorMemoryStorage资源...") + self.stop() + # 全局实例(可选) _global_vector_storage = None diff --git a/src/main.py b/src/main.py index 27c486404..35eb2180c 100644 --- a/src/main.py +++ b/src/main.py @@ -68,96 +68,8 @@ class MainSystem: self.app: MessageServer = get_global_api() self.server: Server = get_global_server() - # 设置信号处理器用于优雅退出 - self._setup_signal_handlers() - - def _setup_signal_handlers(self): - """设置信号处理器""" - - def signal_handler(signum, frame): - logger.info("收到退出信号,正在优雅关闭系统...") - - import asyncio - - try: - loop = asyncio.get_event_loop() - if loop.is_running(): - # 如果事件循环正在运行,创建任务并设置回调 - async def cleanup_and_exit(): - await self._async_cleanup() - sys.exit(0) - - task = asyncio.create_task(cleanup_and_exit()) - # 添加任务完成回调,确保程序退出 - task.add_done_callback(lambda t: None) - else: - # 如果事件循环未运行,使用同步清理 - self._cleanup() - sys.exit(0) - except Exception as e: - logger.error(f"信号处理失败: {e}") - sys.exit(1) - - signal.signal(signal.SIGINT, signal_handler) - signal.signal(signal.SIGTERM, signal_handler) - - async def _async_cleanup(self): - """异步清理资源""" - try: - - # 停止数据库服务 - try: - from src.common.database.database import stop_database - await stop_database() - logger.info("🛑 数据库服务已停止") - except Exception as e: - logger.error(f"停止数据库服务时出错: {e}") - - # 停止消息管理器 - try: - from src.chat.message_manager import message_manager - await message_manager.stop() - logger.info("🛑 消息管理器已停止") - except Exception as e: - logger.error(f"停止消息管理器时出错: {e}") - - # 停止消息重组器 - try: - from src.plugin_system import EventType - from src.plugin_system.core.event_manager import event_manager - from src.utils.message_chunker import reassembler - - await event_manager.trigger_event(EventType.ON_STOP, permission_group="SYSTEM") - await reassembler.stop_cleanup_task() - logger.info("🛑 消息重组器已停止") - except Exception as e: - logger.error(f"停止消息重组器时出错: {e}") - - # 停止增强记忆系统 - try: - if global_config.memory.enable_memory: - await self.memory_manager.shutdown() - logger.info("🛑 增强记忆系统已停止") - except Exception as e: - logger.error(f"停止增强记忆系统时出错: {e}") - - except Exception as e: - logger.error(f"异步清理资源时出错: {e}") - - def _cleanup(self): - """同步清理资源(向后兼容)""" - import asyncio - - try: - loop = asyncio.get_event_loop() - if loop.is_running(): - # 如果循环正在运行,创建异步清理任务 - asyncio.create_task(self._async_cleanup()) - else: - # 如果循环未运行,直接运行异步清理 - loop.run_until_complete(self._async_cleanup()) - except Exception as e: - logger.error(f"同步清理资源时出错: {e}") + # 信号处理现在由bot.py的KeyboardInterrupt处理 + pass async def _message_process_wrapper(self, message_data: dict[str, Any]): """并行处理消息的包装器"""