""" Event Handler 실시간 시세 이벤트 핸들러 관리 """ from enum import Enum from typing import Dict, List, Callable, Any, Awaitable import logging import asyncio logger = logging.getLogger(__name__) class EventType(Enum): """이벤트 타입""" PRICE_UPDATE = "PRICE_UPDATE" # 현재가 업데이트 ORDERBOOK_UPDATE = "ORDERBOOK_UPDATE" # 호가 업데이트 EXECUTION = "EXECUTION" # 체결 발생 ORDER_CONFIRM = "ORDER_CONFIRM" # 주문 체결 확인 ERROR = "ERROR" # 에러 발생 CONNECTED = "CONNECTED" # 연결 성공 DISCONNECTED = "DISCONNECTED" # 연결 해제 class EventHandler: """ 실시간 이벤트 핸들러 관리자 이벤트 타입별로 핸들러 함수를 등록하고 실행 """ def __init__(self): self.handlers: Dict[EventType, List[Callable]] = { event_type: [] for event_type in EventType } self.global_handlers: List[Callable] = [] # 모든 이벤트 수신 logger.info("📡 EventHandler 초기화") def register( self, event_type: EventType, handler: Callable[[Dict[str, Any]], Awaitable[None]] ): """ 이벤트 핸들러 등록 Args: event_type: 이벤트 타입 handler: 비동기 핸들러 함수 (event_data를 받아 처리) """ if handler not in self.handlers[event_type]: self.handlers[event_type].append(handler) logger.info(f"✅ 핸들러 등록: {event_type.value} -> {handler.__name__}") def unregister(self, event_type: EventType, handler: Callable): """핸들러 등록 해제""" if handler in self.handlers[event_type]: self.handlers[event_type].remove(handler) logger.info(f"❌ 핸들러 해제: {event_type.value} -> {handler.__name__}") def register_global(self, handler: Callable[[EventType, Dict[str, Any]], Awaitable[None]]): """모든 이벤트를 수신하는 글로벌 핸들러 등록""" if handler not in self.global_handlers: self.global_handlers.append(handler) logger.info(f"🌍 글로벌 핸들러 등록: {handler.__name__}") async def emit( self, event_type: EventType, event_data: Dict[str, Any] ): """ 이벤트 발생 및 핸들러 실행 Args: event_type: 이벤트 타입 event_data: 이벤트 데이터 """ logger.debug(f"📤 이벤트 발생: {event_type.value}") # 타입별 핸들러 실행 handlers = self.handlers.get(event_type, []) tasks = [] for handler in handlers: try: task = asyncio.create_task(handler(event_data)) tasks.append(task) except Exception as e: logger.error(f"❌ 핸들러 실행 오류 [{handler.__name__}]: {e}", exc_info=True) # 글로벌 핸들러 실행 for global_handler in self.global_handlers: try: task = asyncio.create_task(global_handler(event_type, event_data)) tasks.append(task) except Exception as e: logger.error(f"❌ 글로벌 핸들러 오류: {e}", exc_info=True) # 모든 핸들러 완료 대기 (non-blocking) if tasks: await asyncio.gather(*tasks, return_exceptions=True) def clear(self, event_type: Optional[EventType] = None): """핸들러 초기화""" if event_type: self.handlers[event_type].clear() logger.info(f"🧹 핸들러 초기화: {event_type.value}") else: for handlers in self.handlers.values(): handlers.clear() self.global_handlers.clear() logger.info("🧹 전체 핸들러 초기화") def get_stats(self) -> Dict[str, Any]: """핸들러 통계""" return { "handlers": { event_type.value: len(handlers) for event_type, handlers in self.handlers.items() }, "global_handlers": len(self.global_handlers) } # 싱글톤 event_handler = EventHandler()