Merge branch 'dev' of https://github.com/MaiM-with-u/MaiBot into dev
This commit is contained in:
@@ -2,6 +2,7 @@ import traceback
|
||||
from typing import Optional, Dict
|
||||
import asyncio
|
||||
from asyncio import Lock
|
||||
import threading # 导入 threading
|
||||
from ...moods.moods import MoodManager
|
||||
from ...chat.emoji_manager import emoji_manager
|
||||
from .heartFC_generator import ResponseGenerator
|
||||
@@ -13,7 +14,7 @@ from src.do_tool.tool_use import ToolUser
|
||||
from .interest import InterestManager
|
||||
from src.plugins.chat.chat_stream import chat_manager
|
||||
from .pf_chatting import PFChatting
|
||||
import threading # 导入 threading
|
||||
|
||||
|
||||
# 定义日志配置
|
||||
chat_config = LogConfig(
|
||||
@@ -21,51 +22,73 @@ chat_config = LogConfig(
|
||||
file_format=CHAT_STYLE_CONFIG["file_format"],
|
||||
)
|
||||
|
||||
logger = get_module_logger("HeartFC_Controller", config=chat_config)
|
||||
logger = get_module_logger("HeartFCController", config=chat_config)
|
||||
|
||||
# 检测群聊兴趣的间隔时间
|
||||
INTEREST_MONITOR_INTERVAL_SECONDS = 1
|
||||
|
||||
|
||||
class HeartFC_Controller:
|
||||
# 合并后的版本:使用 __new__ + threading.Lock 实现线程安全单例,类名为 HeartFCController
|
||||
class HeartFCController:
|
||||
_instance = None
|
||||
_lock = threading.Lock() # 使用 threading.Lock 替代 asyncio.Lock 以兼容 __new__
|
||||
_lock = threading.Lock() # 使用 threading.Lock 保证 __new__ 线程安全
|
||||
_initialized = False
|
||||
|
||||
def __new__(cls, *args, **kwargs):
|
||||
if cls._instance is None:
|
||||
with cls._lock:
|
||||
# Double-checked locking
|
||||
if cls._instance is None:
|
||||
logger.debug("创建 HeartFCController 单例实例...")
|
||||
cls._instance = super().__new__(cls)
|
||||
return cls._instance
|
||||
|
||||
def __init__(self):
|
||||
# 使用 _initialized 标志确保 __init__ 只执行一次
|
||||
if self._initialized:
|
||||
return
|
||||
with self.__class__._lock: # 使用类锁确保初始化线程安全
|
||||
if self._initialized:
|
||||
# 虽然 __new__ 保证了只有一个实例,但为了防止意外重入或多线程下的初始化竞争,
|
||||
# 再次使用类锁保护初始化过程是更严谨的做法。
|
||||
# 如果确定 __init__ 逻辑本身是幂等的或非关键的,可以省略这里的锁。
|
||||
# 但为了保持原始逻辑的意图(防止重复初始化),这里保留检查。
|
||||
with self.__class__._lock: # 确保初始化逻辑线程安全
|
||||
if self._initialized: # 再次检查,防止锁等待期间其他线程已完成初始化
|
||||
return
|
||||
logger.info("正在初始化 HeartFC_Controller 单例...")
|
||||
|
||||
logger.info("正在初始化 HeartFCController 单例...")
|
||||
self.gpt = ResponseGenerator()
|
||||
self.mood_manager = MoodManager.get_instance()
|
||||
# 注意:mood_manager 的 start_mood_update 可能需要在应用主循环启动后调用,
|
||||
# 或者确保其内部实现是安全的。这里保持原状。
|
||||
self.mood_manager.start_mood_update()
|
||||
self.tool_user = ToolUser()
|
||||
# 注意:InterestManager() 可能是另一个单例或需要特定初始化。
|
||||
# 假设 InterestManager() 返回的是正确配置的实例。
|
||||
self.interest_manager = InterestManager()
|
||||
self._interest_monitor_task: Optional[asyncio.Task] = None
|
||||
self.pf_chatting_instances: Dict[str, PFChatting] = {}
|
||||
self._pf_chatting_lock = Lock() # 这个可以是 asyncio.Lock,用于异步上下文
|
||||
self.emoji_manager = emoji_manager
|
||||
self.relationship_manager = relationship_manager
|
||||
# _pf_chatting_lock 用于保护 pf_chatting_instances 的异步操作
|
||||
self._pf_chatting_lock = asyncio.Lock() # 这个是 asyncio.Lock,用于异步上下文
|
||||
self.emoji_manager = emoji_manager # 假设是全局或已初始化的实例
|
||||
self.relationship_manager = relationship_manager # 假设是全局或已初始化的实例
|
||||
# MessageManager 可能是类本身或单例实例,根据其设计确定
|
||||
self.MessageManager = MessageManager
|
||||
self._initialized = True
|
||||
logger.info("HeartFC_Controller 单例初始化完成。")
|
||||
logger.info("HeartFCController 单例初始化完成。")
|
||||
|
||||
@classmethod
|
||||
def get_instance(cls):
|
||||
"""获取 HeartFC_Controller 的单例实例。"""
|
||||
"""获取 HeartFCController 的单例实例。"""
|
||||
# 如果实例尚未创建,调用构造函数(这将触发 __new__ 和 __init__)
|
||||
if cls._instance is None:
|
||||
logger.warning("HeartFC_Controller 实例在首次 get_instance 时创建,可能未在 main 中正确初始化。")
|
||||
cls() # 调用构造函数创建
|
||||
# 在首次调用 get_instance 时创建实例。
|
||||
# __new__ 中的锁会确保线程安全。
|
||||
cls()
|
||||
# 添加日志记录,说明实例是在 get_instance 调用时创建的
|
||||
logger.info("HeartFCController 实例在首次 get_instance 时创建。")
|
||||
elif not cls._initialized:
|
||||
# 实例已创建但可能未初始化完成(理论上不太可能发生,除非 __init__ 异常)
|
||||
logger.warning("HeartFCController 实例存在但尚未完成初始化。")
|
||||
return cls._instance
|
||||
|
||||
# --- 新增:检查 PFChatting 状态的方法 --- #
|
||||
@@ -83,9 +106,9 @@ class HeartFC_Controller:
|
||||
|
||||
async def start(self):
|
||||
"""启动异步任务,如回复启动器"""
|
||||
logger.debug("HeartFC_Controller 正在启动异步任务...")
|
||||
logger.debug("HeartFCController 正在启动异步任务...")
|
||||
self._initialize_monitor_task()
|
||||
logger.info("HeartFC_Controller 异步任务启动完成")
|
||||
logger.info("HeartFCController 异步任务启动完成")
|
||||
|
||||
def _initialize_monitor_task(self):
|
||||
"""启动后台兴趣监控任务,可以检查兴趣是否足以开启心流对话"""
|
||||
@@ -105,7 +128,7 @@ class HeartFC_Controller:
|
||||
async with self._pf_chatting_lock:
|
||||
if stream_id not in self.pf_chatting_instances:
|
||||
logger.info(f"为流 {stream_id} 创建新的PFChatting实例")
|
||||
# 传递 self (HeartFC_Controller 实例) 进行依赖注入
|
||||
# 传递 self (HeartFCController 实例) 进行依赖注入
|
||||
instance = PFChatting(stream_id, self)
|
||||
# 执行异步初始化
|
||||
if not await instance._initialize():
|
||||
|
||||
Reference in New Issue
Block a user