"""당일 trade_history — 프로세스 공유 RAM + TTL. check_buy·포트가드가 같은 표를 나눠 씀. SELECT 연타·공유 DB 락 대기 완화. TTL 만료 또는 invalidate 시에만 DB 재조회 (DB 쓰기 아님). """ from __future__ import annotations import threading import time from typing import Any, Dict, List, Optional, Tuple _LOCK = threading.Lock() _DAY: str = "" _ROWS: List[Dict] = [] _TS: float = 0.0 def _ttl_sec() -> float: try: from .env import get_env_float return float(get_env_float("TODAY_TRADES_CACHE_TTL_SEC", 1.0) or 1.0) except Exception: return 1.0 def invalidate_today_trades_cache() -> None: """매수 체결 직후 등 — 다음 get 이 DB 재조회.""" global _DAY, _ROWS, _TS with _LOCK: _DAY = "" _ROWS = [] _TS = 0.0 def get_today_trades_cached( db: Any, today: Optional[str] = None, ) -> Tuple[List[Dict], bool, float]: """Returns: (rows, from_cache, db_ms). from_cache=True 이면 DB 미호출. """ global _DAY, _ROWS, _TS from datetime import datetime as dt day = str(today or dt.now().strftime("%Y%m%d")) ttl = _ttl_sec() now = time.time() with _LOCK: if _DAY == day and (ttl <= 0 or (now - _TS) < ttl): return list(_ROWS), True, 0.0 t0 = time.perf_counter() try: rows = list(db.get_trades_by_date(day) or []) except Exception: rows = [] db_ms = (time.perf_counter() - t0) * 1000.0 with _LOCK: _DAY = day _ROWS = rows _TS = time.time() return list(rows), False, db_ms