fix(event): improve handler enablement check mechanism

This commit is contained in:
InfinityPacer
2024-10-15 14:44:13 +08:00
parent e99913f900
commit 11c10ea783
+40 -17
View File
@@ -6,13 +6,14 @@ import threading
import time import time
import traceback import traceback
import uuid import uuid
from queue import PriorityQueue, Empty from functools import lru_cache
from typing import Callable, Dict, List, Union, Optional from queue import Empty, PriorityQueue
from typing import Callable, Dict, List, Optional, Union
from app.helper.message import MessageHelper from app.helper.message import MessageHelper
from app.helper.thread import ThreadHelper from app.helper.thread import ThreadHelper
from app.log import logger from app.log import logger
from app.schemas.types import EventType, ChainEventType from app.schemas.types import ChainEventType, EventType
from app.utils.limit import ExponentialBackoffRateLimiter from app.utils.limit import ExponentialBackoffRateLimiter
from app.utils.singleton import Singleton from app.utils.singleton import Singleton
@@ -254,24 +255,46 @@ class EventManager(metaclass=Singleton):
handler_info.append(handler_dict) handler_info.append(handler_dict)
return handler_info return handler_info
@staticmethod @classmethod
def __get_handler_identifier(target: Union[Callable, type]) -> str: @lru_cache(maxsize=1000)
def __get_handler_identifier(cls, target: Union[Callable, type]) -> Optional[str]:
""" """
获取处理器或处理器类的唯一标识符,包括模块名和类名 获取处理器或处理器类的唯一标识符,包括模块名和类名/方法名
:param target: 处理器函数或类 :param target: 处理器函数或类
:return: 唯一标识符 :return: 唯一标识符
""" """
if isinstance(target, type): # 统一使用 inspect.getmodule 来获取模块名
# 如果是类,使用模块名和类名 module = inspect.getmodule(target)
module_name = target.__module__ module_name = module.__name__ if module else "unknown_module"
class_name = target.__qualname__
return f"{module_name}.{class_name}" # 使用 __qualname__ 获取目标的限定名
else: qualname = target.__qualname__
# 如果是函数或方法,使用 inspect.getmodule 来获取模块名 return f"{module_name}.{qualname}"
module = inspect.getmodule(target)
@classmethod
@lru_cache(maxsize=1000)
def __get_class_from_callable(cls, handler: Callable) -> Optional[str]:
"""
获取可调用对象所属类的唯一标识符
:param handler: 可调用对象(函数、方法等)
:return: 类的唯一标识符
"""
# 对于绑定方法,通过 __self__.__class__ 获取类
if inspect.ismethod(handler) and hasattr(handler, "__self__"):
return cls.__get_handler_identifier(handler.__self__.__class__)
# 对于类实例(实现了 __call__ 方法)
if not inspect.isfunction(handler) and hasattr(handler, "__call__"):
handler_cls = handler.__class__
return cls.__get_handler_identifier(handler_cls)
# 对于未绑定方法、静态方法、类方法,使用 __qualname__ 提取类信息
qualname_parts = handler.__qualname__.split(".")
if len(qualname_parts) > 1:
class_name = ".".join(qualname_parts[:-1])
module = inspect.getmodule(handler)
module_name = module.__name__ if module else "unknown_module" module_name = module.__name__ if module else "unknown_module"
qualname = target.__qualname__ return f"{module_name}.{class_name}"
return f"{module_name}.{qualname}"
def __is_handler_enabled(self, handler: Callable) -> bool: def __is_handler_enabled(self, handler: Callable) -> bool:
""" """
@@ -283,7 +306,7 @@ class EventManager(metaclass=Singleton):
handler_id = self.__get_handler_identifier(handler) handler_id = self.__get_handler_identifier(handler)
# 获取处理器所属类的唯一标识符 # 获取处理器所属类的唯一标识符
class_id = self.__get_handler_identifier(handler.__self__.__class__) if hasattr(handler, '__self__') else None class_id = self.__get_class_from_callable(handler)
# 检查处理器或类是否被禁用,只要其中之一被禁用则返回 False # 检查处理器或类是否被禁用,只要其中之一被禁用则返回 False
if handler_id in self.__disabled_handlers or (class_id is not None and class_id in self.__disabled_classes): if handler_id in self.__disabled_handlers or (class_id is not None and class_id in self.__disabled_classes):