update: 板块缓存
This commit is contained in:
@@ -6,11 +6,13 @@ import httpx
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from datetime import datetime
|
from datetime import datetime, time as dtime, timedelta, timezone
|
||||||
from typing import Optional, List
|
from typing import Optional, List
|
||||||
|
|
||||||
from services.cache import get_cache, set_cache
|
from services.cache import get_cache, set_cache
|
||||||
|
|
||||||
|
from services.cache import get_cache, set_cache
|
||||||
|
|
||||||
|
|
||||||
# ---- API Key 轮询(MX 备选源用)----
|
# ---- API Key 轮询(MX 备选源用)----
|
||||||
|
|
||||||
@@ -277,6 +279,35 @@ async def get_em_ut(force_refresh: bool = False) -> str:
|
|||||||
return _em_ut
|
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 指纹
|
# curl_cffi 模拟 Chrome TLS 指纹
|
||||||
from curl_cffi.requests import AsyncSession
|
from curl_cffi.requests import AsyncSession
|
||||||
|
|
||||||
@@ -299,26 +330,45 @@ def _get_sector_session() -> AsyncSession:
|
|||||||
return _sector_session
|
return _sector_session
|
||||||
|
|
||||||
|
|
||||||
# 内存缓存
|
# 内存缓存(加速交易时段频繁请求)
|
||||||
_sector_cache: dict[str, tuple[list[dict], float]] = {}
|
_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]:
|
async def fetch_sector_list(sector_type: str) -> list[dict]:
|
||||||
|
# 1. 内存缓存(仅交易时段有效,60s 避免重复请求)
|
||||||
now = time.time()
|
now = time.time()
|
||||||
if sector_type in _sector_cache:
|
if sector_type in _sector_cache:
|
||||||
data, ts = _sector_cache[sector_type]
|
data, ts = _sector_cache[sector_type]
|
||||||
if now - ts < _SECTOR_CACHE_TTL:
|
if now - ts < _SECTOR_MEM_TTL:
|
||||||
return data
|
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)
|
data = await _fetch_push2(sector_type)
|
||||||
if data:
|
if data:
|
||||||
_sector_cache[sector_type] = (data, now)
|
_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
|
return data
|
||||||
|
|
||||||
data = await _fetch_akshare(sector_type)
|
data = await _fetch_akshare(sector_type)
|
||||||
if data:
|
if data:
|
||||||
_sector_cache[sector_type] = (data, now)
|
_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
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user