fix: 热点穿透盘中缓存过期改为同步重建,避免显示上个交易日旧图
fetch_theme_graph 原用 stale-while-revalidate:缓存过期先返回旧数据、 后台异步重建。缓存里若是上个交易日数据,过期后用户一直看到旧图, 重建完成前不会更新。 - 交易时段缓存过期/无缓存 → 同步重建(加锁去重),绝不返回旧数据 - 非交易时段过期 → 保留 stale-while-revalidate(行情无实时变化,秒开无害) 实测盘中同步重建约 7s,可接受。 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+14
-12
@@ -399,10 +399,11 @@ async def _rebuild_task(cache_key: str, sort_field: int, top_n: int, lock: async
|
||||
|
||||
|
||||
async def fetch_theme_graph(sort_field: int = 1, top_n: int = 30, limit: int = 1000) -> dict:
|
||||
"""获取热点穿透图数据(盘中 60s 缓存 + stale-while-revalidate)
|
||||
"""获取热点穿透图数据(盘中 60s 缓存,盘中过期同步重建,非盘中 stale-while-revalidate)
|
||||
|
||||
缓存命中且未过期 → 直接返回;已过期 → 返回旧数据并后台异步重建(秒开);
|
||||
无缓存 → 同步构建(并发下加锁去重)。返回前按 limit 裁剪 stocks。
|
||||
缓存新鲜 → 直接返回;
|
||||
非交易时段过期 → 返回旧数据并后台异步重建(秒开,非盘中行情无实时变化,旧值可接受);
|
||||
交易时段过期 / 无缓存 → 同步重建(加锁去重),绝不返回上个交易日的旧图。
|
||||
|
||||
Args:
|
||||
sort_field: 题材排序 1=涨幅, 4=热度
|
||||
@@ -412,20 +413,21 @@ async def fetch_theme_graph(sort_field: int = 1, top_n: int = 30, limit: int = 1
|
||||
cache_key = f"theme_graph:{sort_field}:{top_n}"
|
||||
|
||||
data, expires_at = _get_graph_cache(cache_key)
|
||||
if data is not None:
|
||||
# 有缓存:新鲜直接返回;过期返回旧数据并后台刷新
|
||||
if not (expires_at and expires_at > time.time()):
|
||||
_spawn_rebuild(cache_key, sort_field, top_n)
|
||||
if data is not None and expires_at and expires_at > time.time():
|
||||
# 缓存新鲜 → 直接返回
|
||||
return _trim_graph_result(data, limit)
|
||||
|
||||
# 无缓存:同步构建(并发下加锁去重)
|
||||
# 非交易时段过期:行情无实时变化,先返回旧值(秒开),后台异步重建
|
||||
if data is not None and not _is_trading_time():
|
||||
_spawn_rebuild(cache_key, sort_field, top_n)
|
||||
return _trim_graph_result(data, limit)
|
||||
|
||||
# 交易时段过期 / 无缓存:同步重建,加锁去重
|
||||
lock = _REBUILD_LOCKS.setdefault(cache_key, asyncio.Lock())
|
||||
async with lock:
|
||||
data, expires_at = _get_graph_cache(cache_key)
|
||||
if data is not None:
|
||||
# 等待锁期间已被其他请求写入
|
||||
if not (expires_at and expires_at > time.time()):
|
||||
_spawn_rebuild(cache_key, sort_field, top_n)
|
||||
if data is not None and expires_at and expires_at > time.time():
|
||||
# 等待锁期间已被其他请求刷新
|
||||
return _trim_graph_result(data, limit)
|
||||
data = await _build_theme_graph(sort_field, top_n)
|
||||
_set_graph_cache(cache_key, data)
|
||||
|
||||
Reference in New Issue
Block a user