feat: realtime_hub 장 시간대 게이팅
장외·주말·휴장 시 키움 WS 연결 안 함(재연결 폭주·로그 노이즈 방지). behive_web._market_phase_state() 지연 import 재사용(active=정규장·NXT만 연결). 장 마감되면 수신 루프가 연결 종료 후 대기 모드(60s 폴링), 개장 시 자동 재연결. 판정 실패 시 보수적으로 연결 유지(fail-open). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -45,6 +45,8 @@ _BACKOFF_MAX = 30.0
|
||||
_MAX_CONN_AGE = 25 * 60
|
||||
# recv 타임아웃 — 이 시간 내 아무것도 안 오면 루프 돌며 stop/age 체크
|
||||
_RECV_TIMEOUT = 5.0
|
||||
# 장 마감 시간대 재확인 주기 — 연결 안 하고 대기하며 이 간격으로 개장 여부 폴링
|
||||
_CLOSED_POLL_SEC = 60.0
|
||||
|
||||
|
||||
def _ws_url() -> str:
|
||||
@@ -135,19 +137,33 @@ class RealtimeHub:
|
||||
pass
|
||||
|
||||
# ---- 내부: 연결 루프 ----
|
||||
def _market_open(self) -> bool:
|
||||
"""장 시간대(정규장·NXT) 여부. behive_web._market_phase_state 재사용(지연 import로 순환 회피).
|
||||
판정 실패 시 보수적으로 True(연결 유지) — 게이팅 때문에 시세가 끊기는 일은 없게."""
|
||||
try:
|
||||
import behive_web
|
||||
return bool(behive_web._market_phase_state().get('active'))
|
||||
except Exception:
|
||||
return True
|
||||
|
||||
def _run(self) -> None:
|
||||
backoff = _BACKOFF_START
|
||||
while not self._stop.is_set():
|
||||
if not self._market_open():
|
||||
# 장 외(주말·휴장·장외 시간) → 연결 안 하고 대기. 재연결 폭주·로그 노이즈 방지.
|
||||
self._connected.clear()
|
||||
self._stop.wait(_CLOSED_POLL_SEC)
|
||||
continue
|
||||
try:
|
||||
self._connect_once()
|
||||
backoff = _BACKOFF_START # 정상 종료(선제 재연결 등) → 백오프 리셋
|
||||
backoff = _BACKOFF_START # 정상 종료(선제 재연결·장 마감 등) → 백오프 리셋
|
||||
except Exception as e:
|
||||
self.last_error = f'{type(e).__name__}: {e}'
|
||||
self._connected.clear()
|
||||
sys.stderr.write(f'[realtime-hub] 연결 끊김/실패: {self.last_error}\n')
|
||||
if self._stop.is_set():
|
||||
break
|
||||
time.sleep(backoff)
|
||||
self._stop.wait(backoff)
|
||||
backoff = min(backoff * 2, _BACKOFF_MAX)
|
||||
|
||||
def _connect_once(self) -> None:
|
||||
@@ -175,10 +191,17 @@ class RealtimeHub:
|
||||
self._send_reg(codes)
|
||||
|
||||
# 3) 수신 루프
|
||||
_last_mkt_check = time.time()
|
||||
while not self._stop.is_set():
|
||||
if time.time() - self.connected_at > _MAX_CONN_AGE:
|
||||
sys.stderr.write('[realtime-hub] 토큰 만료 전 선제 재연결\n')
|
||||
return # 정상 종료 → _run이 즉시 재연결
|
||||
# 장 마감되면 연결 종료 → _run이 대기 모드로 전환. 30초마다만 확인(매 recv마다 X).
|
||||
if time.time() - _last_mkt_check > 30:
|
||||
_last_mkt_check = time.time()
|
||||
if not self._market_open():
|
||||
sys.stderr.write('[realtime-hub] 장 마감 → 연결 종료, 대기 모드\n')
|
||||
return
|
||||
try:
|
||||
raw = ws.recv()
|
||||
except websocket.WebSocketTimeoutException:
|
||||
|
||||
Reference in New Issue
Block a user