6.5 KiB
id, title, status, type, team, supporting_teams, roadmap_item, priority
| id | title | status | type | team | supporting_teams | roadmap_item | priority | |
|---|---|---|---|---|---|---|---|---|
| TASK-220 | Schedule public snapshot refreshes | done | backend | Backend Senior |
|
foundation | high |
TASK-220 - Schedule public snapshot refreshes
Goal
Configure automatic regeneration of public snapshots and read models at appropriate times, so public pages do not depend on heavy runtime calculations.
Context
Public historical, ranking and stats pages should read precomputed data. Heavy regeneration should happen inside the internal runner during low-load windows, while weekly/monthly ranking and recent matches stay fresh at shorter intervals.
Preserve the current product identity: Spanish-speaking HLL Vietnam community, military/Vietnam/tactical/sober visual direction and controlled repository evolution.
Steps
- Inspect the listed files first.
- Document how the current refresh paths work.
- Add environment-driven scheduling for daily full refresh, frequent ranking refresh and recent match snapshot refresh.
- Keep refreshes idempotent and non-overlapping.
- Document Portainer configuration and manual emergency commands.
- Validate Python compilation and scheduler helpers.
Files to Read First
AGENTS.mdai/repo-context.mdai/architecture-index.mdai/orchestrator/backend-senior.mdai/orchestrator/python-architect.mdbackend/app/historical_runner.pybackend/app/rcon_historical_leaderboards.pybackend/app/rcon_annual_rankings.pybackend/app/rcon_historical_player_stats.pybackend/app/historical_snapshot_storage.pybackend/app/historical_snapshots.pybackend/app/payloads.pybackend/app/config.pybackend/app/main.pydocker-compose.ymlREADME.mddocs/PERFORMANCE_PUBLIC_QUERY_AUDIT.md
Expected Files to Modify
backend/app/config.pybackend/app/historical_runner.pybackend/app/historical_snapshots.pybackend/app/routes.pybackend/tests/test_historical_snapshot_refresh.pydocker-compose.ymldocs/public-snapshot-refresh-schedule.mdai/tasks/in-progress/TASK-220-schedule-public-snapshot-refreshes.md
Constraints
- Do not execute
ai-platform run. - Do not push or commit.
- Do not touch frontend except documentation if unavoidable.
- Do not touch weapon assets, SVGs or physical images.
- Do not touch
ai/system-metrics.md. - Do not reactivate Elo/MMR.
- Do not reintroduce Comunidad Hispana #03.
- Keep public requests on read models/snapshots for rankings.
- Prefer the internal runner over host cron.
Validation
Before completing the task ensure:
- Run
python -m compileallfor modified backend modules. - Run relevant existing backend tests if applicable.
- Validate scheduler helper behavior for the next 06:00 Europe/Madrid.
- Confirm public route modules still compile.
- Review
git diff --name-only. - Confirm no frontend, weapon assets, SVGs, physical images or
ai/system-metrics.mdwere modified by this task.
Outcome
Completed.
Current-state analysis:
ranking_snapshotsweekly/monthly were generated byrefresh_ranking_snapshots()and invoked fromhistorical_runneronce per historical runner cycle. Compose forced--hourly, so public rankings could wait up to an hour despite the code recommending 5-15 minute freshness.- Annual ranking snapshots existed through
generate_annual_ranking_snapshot()but were only manual/CLI-driven, not part of the runner schedule. player_search_indexandplayer_period_statswere refreshed fromhistorical_runneronce per runner cycle.- Recent matches were included in full/priority historical snapshots, but there was no dedicated short-cadence refresh. RCON capture exposed
materialized_matches_inserted, which can be used as a finished-match hook. historical_runneralready existed and is the right place for internal scheduling; no host cron is required.- Public historical snapshot leaderboard routes in RCON mode were using a runtime materialized fast path despite being snapshot endpoints.
Implemented strategy:
- Added public refresh env configuration with safe defaults.
- Kept the internal runner as scheduler and removed the Compose
--hourlyoverride so the runner can tick at the shortest public interval while still throttling the heavier historical cycle separately. - Added daily public full refresh logic, due once per local day after
06:00 Europe/Madrid. - Added frequent weekly/monthly ranking snapshot refresh at
HLL_PUBLIC_RANKING_REFRESH_INTERVAL_SECONDS. - Added recent-match-only snapshot generation and scheduled it at
HLL_PUBLIC_RECENT_MATCHES_REFRESH_INTERVAL_SECONDS. - Added immediate recent-match refresh when RCON capture reports newly materialized finished matches.
- Added structured start/end logs, durations and per-step results. Per-step failures are captured without stopping neighboring refreshes or the runner.
- Added in-process non-overlap guards for public refresh classes.
- Changed public historical leaderboard snapshot routes to read persisted snapshots instead of the RCON runtime fast path.
- Documented Portainer configuration and emergency commands in
docs/public-snapshot-refresh-schedule.md.
Validation:
python -m compileall backend/app/config.py backend/app/historical_runner.py backend/app/historical_snapshots.py backend/app/routes.pypython -m compileall backend/app backend/tests$env:PYTHONPATH='backend'; python -m unittest backend.tests.test_historical_snapshot_refresh$env:PYTHONPATH='backend'; python -m unittest backend.tests.test_annual_ranking_payload- Dry-run scheduler helper check:
2026-06-10T03:30:00Z-> next refresh2026-06-10T04:00:00Z(06:00 Europe/Madrid)2026-06-10T05:00:00Z-> next refresh2026-06-11T04:00:00Z
- Route dry-run with patched builder confirmed
/api/historical/snapshots/leaderboardresolves throughbuild_leaderboard_snapshot_payload. git diff --name-onlyreviewed.
Exclusions:
- Did not execute
ai-platform run. - Did not push or commit.
- Did not modify frontend files as part of this task.
- Did not modify physical images, weapon assets, SVGs or
ai/system-metrics.md. - Did not reactivate Elo/MMR.
- Did not reintroduce Comunidad Hispana #03.
Note: the worktree still contains pre-existing unrelated changes in ai/system-metrics.md, frontend/assets/css/styles.css, clan image files and weapon/SVG assets. They were not touched by this task.
Change Budget
- Prefer fewer than 5 modified files when feasible.
- Prefer changes under 200 lines when feasible.
- Split follow-up tasks if scope grows.