Isolate runner read model refresh from legacy snapshot failures

This commit is contained in:
devRaGonSa
2026-06-09 12:34:34 +02:00
parent f341b5510c
commit d9371d6912
7 changed files with 412 additions and 7 deletions

View File

@@ -107,6 +107,8 @@ Automatic runner refresh:
- `backend/app/historical_runner.py` refreshes `player_period_stats` automatically
- it inherits the periodic cadence of the historical runner via `HLL_HISTORICAL_REFRESH_INTERVAL_SECONDS`
- the runner executes this step after `player_search_index` and before `ranking_snapshots`
- the runner still attempts this step even if the legacy historical snapshot block fails earlier in the same cycle
- the overall runner result may end as `partial` when that legacy block fails but operational PostgreSQL refreshes continue
- the public profile path keeps runtime fallback preserved if the read model is empty, incomplete or unavailable
Emergency manual command:
@@ -160,6 +162,10 @@ Indexes kept for the public profile flow:
Recommended checks after refresh:
- confirm the historical runner output reports either `status=ok` or `status=partial`
- confirm `historical_snapshot_result`, `player_search_index_result`, `player_period_stats_result` and `ranking_snapshot_result` are present in the cycle payload
- if the cycle is `partial`, inspect `historical_snapshot_result.error_type`, `historical_snapshot_result.error` and the runner logs for the legacy failure
- confirm `player_period_stats.updated_at` advanced even when a legacy snapshot error was reported
- confirm the historical runner output reports `player_period_stats_result`
- if an emergency rebuild is needed, run `python -m app.rcon_historical_player_stats refresh-player-period-stats`
- confirm the command reports rows for:

View File

@@ -76,6 +76,8 @@ Automatic runner refresh:
- `backend/app/historical_runner.py` refreshes `player_search_index` automatically
- it inherits the periodic cadence of the historical runner via `HLL_HISTORICAL_REFRESH_INTERVAL_SECONDS`
- the runner executes this step after the existing RCON ingestion/materialization cycle
- the runner still attempts this step even if the legacy historical snapshot block fails earlier in the same cycle
- the overall runner result may end as `partial` when that legacy block fails but operational PostgreSQL refreshes continue
- the runner keeps runtime fallback preserved for the public endpoint
Emergency manual command:
@@ -133,6 +135,10 @@ Search tolerance is implemented with:
Recommended checks after refresh:
- confirm the historical runner output reports either `status=ok` or `status=partial`
- confirm `historical_snapshot_result`, `player_search_index_result`, `player_period_stats_result` and `ranking_snapshot_result` are present in the cycle payload
- if the cycle is `partial`, inspect `historical_snapshot_result.error_type`, `historical_snapshot_result.error` and the runner logs for the legacy failure
- confirm `player_search_index.updated_at` advanced even when a legacy snapshot error was reported
- confirm the historical runner output reports `player_search_index_result`
- if an emergency rebuild is needed, run `python -m app.rcon_historical_player_stats refresh-player-search-index`
- confirm the command reports rows for `all-servers`, `comunidad-hispana-01` and `comunidad-hispana-02`

View File

@@ -295,10 +295,12 @@ Current implementation note:
- the periodic historical runner in `backend/app/historical_runner.py` invokes that bulk refresh as part of the normal backend refresh cycle
- current cycle order is:
- existing RCON ingestion/materialization cycle
- legacy `historical_snapshot_result`
- `player_search_index`
- `player_period_stats`
- `ranking_snapshots`
- per-combination failures should be reported without aborting the entire matrix refresh
- a legacy historical snapshot failure can leave the full cycle in `partial`, but the runner should still attempt the operational PostgreSQL refreshes and report `ranking_snapshot_result`
## Recommended Combinations
@@ -329,6 +331,8 @@ Operational guidance:
- regenerate after metric SQL changes that affect ranking totals or ordering
- when using the periodic backend runner, keep ranking refresh attached to the same recurring cycle rather than a separate scheduler unless operational load proves otherwise
- the runner inherits its cadence from `HLL_HISTORICAL_REFRESH_INTERVAL_SECONDS`
- if the runner reports `partial`, review `historical_snapshot_result` and backend logs before assuming `ranking_snapshots` was skipped
- confirm `ranking_snapshots.generated_at` or the latest `updated_at`/window timestamp advanced in PostgreSQL even when a legacy snapshot error was logged
- fallback runtime remains preserved for `/api/ranking` if a requested snapshot is missing or unavailable
## Ready Vs Fallback