129 lines
4.3 KiB
Python
129 lines
4.3 KiB
Python
"""
|
|
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()
|