refactor(phase3): Create realtime module core structure

This commit is contained in:
2026-03-06 10:57:40 +09:00
parent a322745cf3
commit 7355df6ebf
3 changed files with 299 additions and 0 deletions

View File

@@ -0,0 +1,128 @@
"""
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()