fix(recap): speed up /card lookup, fix stale completed-season cache, add Place Finished
- /card player lookup was a leading-wildcard substring match with a Python ulower() UDF over 6.16M player_games_hist rows — a full scan measured at 27s live before the ~2s render. Add a prefix fast-path (nick LIKE 'name%' COLLATE NOCASE) that uses the existing NOCASE index (~1ms), falling back to the ulower substring scan only when the prefix finds nothing. Same fix applied to _resolve_player_uids_batch (compare/stats). Lookup: 27,205ms -> 1ms. - Completed-season recap cache served ANY cached PNG forever, including files rendered mid-season (frozen at whatever point they were last viewed). Only serve from cache when the file's mtime is after season end; otherwise re-render. Fixed in both BOT/utils.py and web/server.js (shared cache). - Replace squadron card "Rating change" with "Place finished" (#rank / total), derived by ranking clans by final total_score among those active in-season. - Add (CARD)/(RECAP) timing logs for prod observability. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+15
-1
@@ -2161,14 +2161,19 @@ async def _get_recap(
|
||||
try:
|
||||
stat = cache_path.stat()
|
||||
if season_range["status"] == "completed":
|
||||
serve_from_cache = True
|
||||
# A completed season's card is only final if it was rendered AFTER
|
||||
# the season ended. Files rendered mid-season are stale snapshots
|
||||
# frozen at whatever point they were last viewed — re-render those.
|
||||
serve_from_cache = stat.st_mtime > season_range["end"]
|
||||
elif (time.time() - stat.st_mtime) < RECAP_TTL_SECONDS:
|
||||
serve_from_cache = True
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
|
||||
ident = clan_id if mode == "squadron" else uid
|
||||
if not serve_from_cache:
|
||||
cache_dir.mkdir(parents=True, exist_ok=True)
|
||||
t0 = time.monotonic()
|
||||
await _spawn_recap_render(
|
||||
mode,
|
||||
clan_id=clan_id,
|
||||
@@ -2181,6 +2186,15 @@ async def _get_recap(
|
||||
theme=theme,
|
||||
lang=lang,
|
||||
)
|
||||
logging.info(
|
||||
"(RECAP) %s id=%s season=%s theme=%s lang=%s result=fresh ms=%d",
|
||||
mode, ident, season, theme, lang, (time.monotonic() - t0) * 1000,
|
||||
)
|
||||
else:
|
||||
logging.info(
|
||||
"(RECAP) %s id=%s season=%s theme=%s lang=%s result=cache",
|
||||
mode, ident, season, theme, lang,
|
||||
)
|
||||
|
||||
if not cache_path.exists():
|
||||
raise RecapError("recap file missing after render")
|
||||
|
||||
Reference in New Issue
Block a user