fix: invalidate stale 12-item volume rank cache and force full top20 refresh

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-08 16:01:27 +08:00
parent 89a58c7323
commit 93b84da72e
5 changed files with 94 additions and 24 deletions
+34 -6
View File
@@ -12,7 +12,7 @@ from zoneinfo import ZoneInfo
from hub_trades_lib import trading_day_from_dt
TOP_N_DEFAULT = 20
CACHE_VERSION = 2
CACHE_VERSION = 3
def volume_rank_reset_hour() -> int:
@@ -471,16 +471,40 @@ def merge_exchange_rank(
return out
def cache_needs_refresh(cache: dict[str, Any], *, expected_rank_date: str | None = None) -> bool:
def _exchange_rank_row_stale(row: dict[str, Any] | None) -> bool:
if not row:
return True
items = row.get("items") or []
if len(items) < TOP_N_DEFAULT:
return True
total = int(row.get("total_symbols") or 0)
if total > 0 and total < TOP_N_DEFAULT:
return True
return False
def cache_needs_refresh(
cache: dict[str, Any],
*,
expected_rank_date: str | None = None,
required_keys: list[str] | None = None,
) -> bool:
expected = expected_rank_date or rank_date_label()
if int(cache.get("version") or 0) < CACHE_VERSION:
return True
if not cache.get("exchanges"):
exchanges = cache.get("exchanges") or {}
if not exchanges:
return True
if str(cache.get("rank_date") or "") != expected:
return True
for _key, row in (cache.get("exchanges") or {}).items():
if not row or not row.get("items"):
keys = required_keys or list(exchanges.keys())
if not keys:
return True
for key in keys:
ex_k = str(key or "").strip().lower()
if not ex_k:
continue
if _exchange_rank_row_stale(exchanges.get(ex_k)):
return True
return False
@@ -494,12 +518,16 @@ def get_cached_rank(
ex_k = str(exchange_key or "").strip().lower()
ex_data = (cache.get("exchanges") or {}).get(ex_k) or {}
items = list(ex_data.get("items") or [])[: max(1, int(top_n))]
stale = _exchange_rank_row_stale(ex_data)
return {
"ok": True,
"exchange_key": ex_k,
"rank_date": ex_data.get("rank_date") or cache.get("rank_date"),
"updated_at": cache.get("updated_at"),
"items": items,
"item_count": len(items),
"expected_count": int(top_n),
"total_symbols": int(ex_data.get("total_symbols") or 0),
"stale": False,
"stale": stale,
"error": ex_data.get("error"),
}