from typing import Dict, List, Callable, Any from fastapi import BackgroundTasks import asyncio import logging from enum import Enum import time logger = logging.getLogger(__name__) class EventPriority(Enum): HIGH = 1 MEDIUM = 2 LOW = 3 class EventType: # 同步星云联系人信息 SYNC_XINGYUN_CONTACT_INFO = "sync_xingyun_contact_info" # 绑定订单给用户 BIND_ORDER_FOR_USER = "bind_order_for_user" # 打开个人聊天会话 OPEN_PERSONAL_CHAT = "open_personal_chat" # 群聊变更 GROUP_CHAT_UPDATED = "group_chat_updated" # 检查创建群聊 CHECK_CREATE_GROUP_CHAT = "check_create_group_chat" # 客服领单 CUSTOMER_SERVICE_ASSIGN_ORDER = "customer_service_assign_order" # 分配设计师 DESIGNER_ASSIGN_ORDER = "designer_assign_order" # 客户复购 OLD_CUSTOMER_REPEAT_PURCHASE = "old_customer_repeat_purchase" # 客户退货 CUSTOMER_RETURN_ORDER = "customer_return_order" # 设计稿上传 DESIGNER_UPLOAD_DESIGN = "designer_upload_design" # 客户在新店铺下单 CUSTOMER_ORDER_IN_NEW_SHOP = "customer_order_in_new_shop" EventList = [ { "value": EventType.SYNC_XINGYUN_CONTACT_INFO, "label": "同步星云联系人信息", "description": "当星云联系人信息发生变化时触发", "automation_event": False }, { "value": EventType.BIND_ORDER_FOR_USER, "label": "绑定订单", "description": "当用户创建订单时触发", "automation_event": True }, { "value": EventType.OPEN_PERSONAL_CHAT, "label": "打开个人聊天会话", "description": "当用户创建个人聊天时触发", "automation_event": False }, { "value": EventType.GROUP_CHAT_UPDATED, "label": "群聊变更", "description": "当群聊信息发生变化时触发", "automation_event": True }, { "value": EventType.CHECK_CREATE_GROUP_CHAT, "label": "群聊创建", "description": "当用户请求创建群聊时触发", "automation_event": True }, { "value": EventType.CUSTOMER_SERVICE_ASSIGN_ORDER, "label": "客服领单", "description": "当客服领单时触发", "automation_event": True }, { "value": EventType.DESIGNER_ASSIGN_ORDER, "label": "分配设计师", "description": "当分配设计师时触发", "automation_event": True }, { "value": EventType.OLD_CUSTOMER_REPEAT_PURCHASE, "label": "客户复购", "description": "当老客复购时触发", "automation_event": True }, { "value": EventType.CUSTOMER_RETURN_ORDER, "label": "客户退货", "description": "当客户退货时触发", "automation_event": True }, { "value": EventType.DESIGNER_UPLOAD_DESIGN, "label": "设计稿上传", "description": "当设计师上传设计稿时触发", "automation_event": True }, { "value": EventType.CUSTOMER_ORDER_IN_NEW_SHOP, "label": "客户在新店铺下单", "description": "当客户在新店铺下单时触发", "automation_event": True }, ] class NonBlockingEventManager: def __init__(self): self.handlers: Dict[str, List[Callable]] = {} self.priority_handlers: Dict[EventPriority, List[Callable]] = { EventPriority.HIGH: [], EventPriority.MEDIUM: [], EventPriority.LOW: [] } self.pretasks: List[Callable] = [] self.automation_event_handlers: Dict[str, Any] = [] def subscribe(self, event_type: str, handler: Callable, priority: EventPriority = EventPriority.MEDIUM, input_model: Any = None): if event_type not in self.handlers: self.handlers[event_type] = [] for event in EventList: if event["value"] == event_type: event["field_tree"] = input_model self.automation_event_handlers.append(event) logger.info(f"Subscribe {event_type} with priority {priority}") # print(f"Subscribe {event_type} with priority {priority}", flush=True) self.handlers[event_type].append(handler) def subscribe_priority(self, handler: Callable, priority: EventPriority = EventPriority.MEDIUM): """订阅所有事件类型的处理器,按优先级""" self.priority_handlers[priority].append(handler) async def publish_async(self, event_type: str, data: Any, background_tasks: BackgroundTasks): """异步发布事件,不阻塞主线程""" # 添加到后台任务,立即返回 background_tasks.add_task( self._process_event_async, event_type, data ) def register_pretask(self, pretask: Callable): """注册预任务""" self.pretasks.append(pretask) async def trigger_event(self, event_type: str, event_data: Any): """解析事件数据""" for pretask in self.pretasks: await pretask(event_type, event_data) async def _process_event_async(self, event_type: str, data: Any): """异步处理事件""" start_time = time.time() # 触发事件系统 try: await self.trigger_event(event_type, data) except Exception as e: logger.exception(f'处理事件失败,{e}') # 处理优先级处理器(高优先级先执行) for priority in [EventPriority.HIGH, EventPriority.MEDIUM, EventPriority.LOW]: priority_tasks = [] for handler in self.priority_handlers[priority]: try: if asyncio.iscoroutinefunction(handler): task = handler(event_type, data) else: task = asyncio.to_thread(handler, event_type, data) priority_tasks.append(task) except Exception as e: logger.error(f"Error in priority handler: {e}") if priority_tasks: await asyncio.gather(*priority_tasks, return_exceptions=True) # 处理特定事件类型的处理器 if event_type in self.handlers: specific_tasks = [] for handler in self.handlers[event_type]: try: if asyncio.iscoroutinefunction(handler): task = handler(event_type, data) else: task = asyncio.to_thread(handler, event_type, data) specific_tasks.append(task) except Exception as e: logging.error(f"Error in specific handler: {e}") if specific_tasks: await asyncio.gather(*specific_tasks, return_exceptions=True) logging.info(f"Event {event_type} processed in {time.time() - start_time:.2f}s") # 创建全局事件管理器 event_manager = NonBlockingEventManager() # # 定义事件处理器 # async def log_event_handler(event_type: str, data: Any): # await asyncio.sleep(0.1) # 模拟异步日志记录 # logging.info(f"Logged event: {event_type}") # def update_cache_handler( Any): # import time # time.sleep(0.5) # 模拟缓存更新 # logging.info(f"Cache updated with: {data}") # # 注册处理器 # event_manager.subscribe_priority(log_event_handler, EventPriority.HIGH) # event_manager.subscribe("order_created", update_cache_handler, EventPriority.MEDIUM) # @app.post("/orders") # async def create_order_complete(order_ dict, background_tasks: BackgroundTasks): # # 执行主要业务逻辑 # order_id = f"order_{hash(str(order_data))}" # order_data["order_id"] = order_id # # 保存到数据库 # # await save_order_to_db(order_data) # # 立即返回响应 # response = {"order_id": order_id, "status": "created"} # # 异步发布事件,不阻塞响应 # await event_manager.publish_async("order_created", order_data, background_tasks) # return response # # 启动时配置 # @app.on_event("startup") # async def startup_event(): # logging.basicConfig(level=logging.INFO)