mirror of
https://ghfast.top/https://github.com/aeroxw/tick-stock-panel.git
synced 2026-09-12 17:54:15 +08:00
fix(rps): 轮动矩阵缓存按覆盖天数复用, 切到更长窗口不再少列
打开「概念分析 → 涨幅RPS轮动」时先看 7 日再切到 30 日, 矩阵只有 25 列。
build_rps_rotation 按 days 换算日历窗口读 enriched (days=7 只读 24 个自然日),
但结果缓存键是 "{kind}|{level}|{latest}", 不含 days。120s TTL 内第二次请求
命中第一次那份按 7 日窗口算出来的矩阵, _slice_cached 又因为 len(dates) <= days
原样返回, 于是请求 30 列拿到 25 列。
记录每个缓存条目实际覆盖的天数, 只在覆盖天数 >= 请求天数时复用; 反方向
(宽窗缓存服务窄请求) 仍按原样 slice 复用。
This commit is contained in:
@@ -35,12 +35,16 @@ logger = logging.getLogger(__name__)
|
||||
_CACHE_TTL = 120.0
|
||||
_cache: dict[str, dict] = {}
|
||||
_cache_ts: dict[str, float] = {}
|
||||
# 该条目实际覆盖的天数: enriched 只读 days 换算出的日历窗口, 缓存的"全量"因此
|
||||
# 以写入时的 days 为上限, 请求更长窗口时不能复用 (见 build_rps_rotation)。
|
||||
_cache_days: dict[str, int] = {}
|
||||
|
||||
|
||||
def invalidate_cache() -> None:
|
||||
"""清空轮动矩阵结果缓存(数据管道完成后调用, 避免返回旧数据)。"""
|
||||
_cache.clear()
|
||||
_cache_ts.clear()
|
||||
_cache_days.clear()
|
||||
|
||||
|
||||
def _latest_enriched_date(repo) -> date | None:
|
||||
@@ -138,7 +142,11 @@ def build_rps_rotation(repo, days: int = 12, kind: str = "concept", level: int |
|
||||
cache_key = f"{kind}|{level}|{latest.isoformat()}"
|
||||
now = time.time()
|
||||
cached = _cache.get(cache_key)
|
||||
if cached and (now - _cache_ts.get(cache_key, 0)) < _CACHE_TTL:
|
||||
if (
|
||||
cached
|
||||
and _cache_days.get(cache_key, 0) >= days
|
||||
and (now - _cache_ts.get(cache_key, 0)) < _CACHE_TTL
|
||||
):
|
||||
return _slice_cached(cached, days)
|
||||
|
||||
# 1. 维度映射(symbol → 维度成员), 已按 kind 缓存为 (map_df, count) 元组 (#186)。
|
||||
@@ -201,9 +209,10 @@ def build_rps_rotation(repo, days: int = 12, kind: str = "concept", level: int |
|
||||
"concept_count": member_count,
|
||||
}
|
||||
|
||||
# 写缓存(存全量, 按需 slice)
|
||||
# 写缓存(存本次窗口的全量, 按需 slice; 覆盖天数一并记下)
|
||||
_cache[cache_key] = full
|
||||
_cache_ts[cache_key] = now
|
||||
_cache_days[cache_key] = days
|
||||
|
||||
return _slice_cached(full, days)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user