feat: add parallel caching for individual stock analysis using asyncio.gather
This commit is contained in:
@@ -87,7 +87,7 @@ async def batch_analysis_scheduler():
|
|||||||
"""
|
"""
|
||||||
await asyncio.sleep(15) # 부팅 안정화 (auto_trade_scheduler보다 늦게 시작)
|
await asyncio.sleep(15) # 부팅 안정화 (auto_trade_scheduler보다 늦게 시작)
|
||||||
from app.api.endpoints.recommendations import get_rule_based_recommendations_realtime
|
from app.api.endpoints.recommendations import get_rule_based_recommendations_realtime
|
||||||
from app.core.redis import setex_json, TTL_RECOMMENDATIONS
|
from app.core.redis import setex_json, TTL_RECOMMENDATIONS, TTL_ANALYSIS
|
||||||
|
|
||||||
interval = int(getattr(settings, "BATCH_ANALYSIS_INTERVAL", 600)) # 기본 10분
|
interval = int(getattr(settings, "BATCH_ANALYSIS_INTERVAL", 600)) # 기본 10분
|
||||||
logger.info(f"📊 Batch analysis scheduler started (every {interval}s)")
|
logger.info(f"📊 Batch analysis scheduler started (every {interval}s)")
|
||||||
@@ -115,6 +115,20 @@ async def batch_analysis_scheduler():
|
|||||||
f"(rule 수: {len(normalized.get('recommendations_by_rule', {}))}, "
|
f"(rule 수: {len(normalized.get('recommendations_by_rule', {}))}, "
|
||||||
f"TTL: {TTL_RECOMMENDATIONS}s)"
|
f"TTL: {TTL_RECOMMENDATIONS}s)"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# ===== 개별 종목별 캐시 (병렬 처리 적용) =====
|
||||||
|
raw_list = result.get("recommendations", [])
|
||||||
|
cache_tasks = []
|
||||||
|
|
||||||
|
for item in raw_list:
|
||||||
|
code = item.get("stock_code") or item.get("code")
|
||||||
|
if code:
|
||||||
|
cache_tasks.append(setex_json(f"analysis:{code}", TTL_ANALYSIS, item))
|
||||||
|
|
||||||
|
if cache_tasks:
|
||||||
|
await asyncio.gather(*cache_tasks, return_exceptions=True)
|
||||||
|
logger.info(f"💾 [Batch] 개별 종목 분석 데이터 캐시 갱신 완료: {len(cache_tasks)}건 (TTL: {TTL_ANALYSIS}s)")
|
||||||
|
# ===============================================
|
||||||
# ───────────────────────────────────────────────────────
|
# ───────────────────────────────────────────────────────
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -524,7 +538,7 @@ async def health_check():
|
|||||||
|
|
||||||
@app.websocket("/ws/{client_id}")
|
@app.websocket("/ws/{client_id}")
|
||||||
async def websocket_endpoint(websocket: WebSocket, client_id: str):
|
async def websocket_endpoint(websocket: WebSocket, client_id: str):
|
||||||
"""WebSocket 연결 엔드포인트.
|
\"\"\"WebSocket 연결 엔드포인트.
|
||||||
|
|
||||||
클라이언트→서버 지원 프로토콜:
|
클라이언트→서버 지원 프로토콜:
|
||||||
{"type": "ping"} → {"type": "pong"}
|
{"type": "ping"} → {"type": "pong"}
|
||||||
@@ -534,7 +548,7 @@ async def websocket_endpoint(websocket: WebSocket, client_id: str):
|
|||||||
{"type": "get_chart", "stock_code": "...", "period": "D", "limit": 200}
|
{"type": "get_chart", "stock_code": "...", "period": "D", "limit": 200}
|
||||||
→ {"type": "chart_data", ...}
|
→ {"type": "chart_data", ...}
|
||||||
그 외 메시지 → echo
|
그 외 메시지 → echo
|
||||||
"""
|
\"\"\"
|
||||||
await websocket_manager.connect(websocket, client_id)
|
await websocket_manager.connect(websocket, client_id)
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
|
|||||||
Reference in New Issue
Block a user