update: 板块缓存
This commit is contained in:
@@ -6,11 +6,13 @@ import httpx
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
from datetime import datetime
|
||||
from datetime import datetime, time as dtime, timedelta, timezone
|
||||
from typing import Optional, List
|
||||
|
||||
from services.cache import get_cache, set_cache
|
||||
|
||||
from services.cache import get_cache, set_cache
|
||||
|
||||
|
||||
# ---- API Key 轮询(MX 备选源用)----
|
||||
|
||||
@@ -277,6 +279,35 @@ async def get_em_ut(force_refresh: bool = False) -> str:
|
||||
return _em_ut
|
||||
|
||||
|
||||
# ---- 板块数据(市场时间感知缓存)----
|
||||
|
||||
_CST = timezone(timedelta(hours=8)) # 北京时间
|
||||
_TRADING_MORNING = (dtime(9, 30), dtime(11, 30))
|
||||
_TRADING_AFTERNOON = (dtime(13, 0), dtime(15, 0))
|
||||
|
||||
|
||||
def _cst_now() -> datetime:
|
||||
return datetime.now(_CST)
|
||||
|
||||
|
||||
def _is_trading_time() -> bool:
|
||||
"""判断当前是否为 A 股交易时段(周一至周五 9:30-11:30 / 13:00-15:00)"""
|
||||
now = _cst_now()
|
||||
if now.weekday() >= 5:
|
||||
return False
|
||||
t = now.time()
|
||||
return (_TRADING_MORNING[0] <= t <= _TRADING_MORNING[1]
|
||||
or _TRADING_AFTERNOON[0] <= t <= _TRADING_AFTERNOON[1])
|
||||
|
||||
|
||||
def _sector_ttl_hours() -> int:
|
||||
"""根据是否在交易时段返回缓存 TTL
|
||||
- 交易时段: 2 分钟(数据持续变化)
|
||||
- 非交易时段: 18 小时(覆盖到下一个交易日)
|
||||
"""
|
||||
return 0 if _is_trading_time() else 18
|
||||
|
||||
|
||||
# curl_cffi 模拟 Chrome TLS 指纹
|
||||
from curl_cffi.requests import AsyncSession
|
||||
|
||||
@@ -299,26 +330,45 @@ def _get_sector_session() -> AsyncSession:
|
||||
return _sector_session
|
||||
|
||||
|
||||
# 内存缓存
|
||||
# 内存缓存(加速交易时段频繁请求)
|
||||
_sector_cache: dict[str, tuple[list[dict], float]] = {}
|
||||
_SECTOR_CACHE_TTL = 60
|
||||
_SECTOR_MEM_TTL = 60
|
||||
|
||||
|
||||
async def fetch_sector_list(sector_type: str) -> list[dict]:
|
||||
# 1. 内存缓存(仅交易时段有效,60s 避免重复请求)
|
||||
now = time.time()
|
||||
if sector_type in _sector_cache:
|
||||
data, ts = _sector_cache[sector_type]
|
||||
if now - ts < _SECTOR_CACHE_TTL:
|
||||
if now - ts < _SECTOR_MEM_TTL:
|
||||
return data
|
||||
|
||||
cache_key = f"sector_list:{sector_type}"
|
||||
|
||||
# 2. 非交易时段:走磁盘持久缓存,不请求 API
|
||||
if not _is_trading_time():
|
||||
cached = get_cache(cache_key)
|
||||
if cached is not None:
|
||||
data = json.loads(cached)
|
||||
_sector_cache[sector_type] = (data, now)
|
||||
return data
|
||||
|
||||
# 3. 请求 API
|
||||
data = await _fetch_push2(sector_type)
|
||||
if data:
|
||||
_sector_cache[sector_type] = (data, now)
|
||||
ttl = _sector_ttl_hours()
|
||||
# 交易时段 ttl=0 → 不写磁盘(内存缓存已够)
|
||||
if ttl > 0:
|
||||
set_cache(cache_key, json.dumps(data, ensure_ascii=False), ttl_hours=ttl)
|
||||
return data
|
||||
|
||||
data = await _fetch_akshare(sector_type)
|
||||
if data:
|
||||
_sector_cache[sector_type] = (data, now)
|
||||
ttl = _sector_ttl_hours()
|
||||
if ttl > 0:
|
||||
set_cache(cache_key, json.dumps(data, ensure_ascii=False), ttl_hours=ttl)
|
||||
return data
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user