12 KiB
id, title, status, type, team, supporting_teams, roadmap_item, priority
| id | title | status | type | team | supporting_teams | roadmap_item | priority | |
|---|---|---|---|---|---|---|---|---|
| TASK-270 | Restore current-live RCON worker deployment | done | documentation | Backend Senior |
|
current-match | high |
TASK-270 - Restore current-live RCON worker deployment
Goal
Restore the existing production-good rcon-historical-worker deployment behavior so current-match AdminLog freshness uses the worker's supported current-live mode instead of the heavy historical loop.
Context
The current GitHub/test deployment starts rcon-historical-worker as python -m app.rcon_historical_worker loop, which resolves to historical capture with heavy materialization enabled. Logs described in the task context show capture_mode=historical, materialization_skipped=false, and interval_seconds=2, which is the wrong runtime shape for current-match freshness.
The backend code already supports the lower-risk production-good path:
backend/app/rcon_historical_worker.pysupports--capture-mode current-live,--interval,--retries, and--retry-delaybackend/app/config.pyresolvesHLL_RCON_CURRENT_MATCH_MODE=trueorHLL_RCON_SKIP_HISTORICAL_MATERIALIZATION=truetocurrent-livecurrent-livealways skips heavy historical materialization and uses the short current-match writer-lock timeout
Mandatory comparison result:
- Uploaded ZIP artifact: no ZIP file matching the described production export was present in the local workspace, so an exact filesystem path inside the ZIP could not be cited directly.
- Known-good repository reference matching the described ZIP behavior:
deploy/jta/docker-compose.yml - Current repo/deployment file missing or overriding that behavior:
deploy/portainer/docker-compose.nas.yml - Root
docker-compose.ymlis not the likely current Portainer stack file because it setscontainer_name: hll-vietnam-rcon-historical-worker, while the running container name provided in the request ishll-vietnam-rcon-historical-worker-1 - The running container name strongly matches the Compose service
rcon-historical-workerfrom a stack deployment withoutcontainer_name, which fitsdeploy/portainer/docker-compose.nas.yml deploy/jta/docker-compose.ymlalready contains the production-goodcurrent-livecommand and env pattern and serves as the checked-in known-good comparison point
Steps
- Compare the worker CLI/config support with the deployment compose variants in the repository.
- Update only the deployment compose file that likely backs the current Portainer stack.
- Keep
backend/app/rcon_current_match_worker.pyinactive in deployment. - Update documentation to reflect that current-match freshness should come from
rcon-historical-workerincurrent-livemode. - Validate compose syntax and confirm no unrelated files changed.
Files to Read First
AGENTS.mdai/architecture-index.mdai/repo-context.mdai/orchestrator/backend-senior.mdbackend/app/rcon_historical_worker.pybackend/app/config.pydeploy/portainer/docker-compose.nas.ymldeploy/jta/docker-compose.ymldocs/current-match-adminlog-freshness.mdai/tasks/done/TASK-269-implement-current-match-adminlog-freshness-worker.md
Expected Files to Modify
deploy/portainer/docker-compose.nas.ymldocs/current-match-adminlog-freshness.mdai/tasks/done/TASK-270-restore-current-live-rcon-worker-deployment.md
Constraints
- Do not run
ai-platform run. - Do not commit or push.
- Do not touch frontend except for documentation references.
- Do not touch physical assets or
frontend/assets/img/. - Do not change RCON hosts, ports, passwords,
external_server_id,target_key, server list, or27001. - Do not change
historical-runner. - Do not activate
backend/app/rcon_current_match_worker.pyin this task. - Do not reactivate Elo/MMR.
- Do not reintroduce
comunidad-hispana-03. - Do not touch
ai/system-metrics.md. - Do not include
tmp/or unrelated pending changes.
Validation
Before completing the task ensure:
python -m app.rcon_historical_worker --helpdocker compose -f deploy/portainer/docker-compose.nas.yml --env-file deploy/portainer/stack.env.example config- optional backend sanity because Python code was not changed:
python -m compileall backend/appcd backend; python -m unittest tests.test_rcon_historical_worker tests.test_current_match_payload
git diff --name-onlymatches the expected scope
Outcome
What was wrong in the current deployment:
rcon-historical-workerwas deployed as the heavy historical loop instead of the existing lightweightcurrent-livepath- this lets frequent materialization hold the shared writer lock
- it blocks
historical_runnerand also collides with the new dedicated TASK-269 worker if both are active - deadlock risk increases under PostgreSQL because multiple writers contend around the same persisted read-model refresh path
What the known-good production behavior did correctly:
- reused
python -m app.rcon_historical_workerinstead of introducing a second always-on worker - ran it in
current-livemode - skipped heavy historical materialization
- used a short interval and short writer-lock timeout to keep current-match AdminLog/read-model freshness moving
Exact service changed:
- service:
rcon-historical-worker - likely running container:
hll-vietnam-rcon-historical-worker-1 - file changed:
deploy/portainer/docker-compose.nas.yml
Exact command/env before:
- command:
python -m app.rcon_historical_worker loop - env:
HLL_RCON_HISTORICAL_CAPTURE_INTERVAL_SECONDS=${HLL_RCON_HISTORICAL_CAPTURE_INTERVAL_SECONDS:-600}HLL_RCON_HISTORICAL_CAPTURE_MAX_RETRIES=${HLL_RCON_HISTORICAL_CAPTURE_MAX_RETRIES:-2}HLL_RCON_HISTORICAL_CAPTURE_RETRY_DELAY_SECONDS=${HLL_RCON_HISTORICAL_CAPTURE_RETRY_DELAY_SECONDS:-15}- no
HLL_RCON_CURRENT_MATCH_MODE - no
HLL_RCON_SKIP_HISTORICAL_MATERIALIZATION - no
HLL_RCON_CURRENT_MATCH_CAPTURE_INTERVAL_SECONDS - no
HLL_RCON_CURRENT_MATCH_WRITER_LOCK_TIMEOUT_SECONDS
Exact command/env after:
- command:
python -m app.rcon_historical_worker loop --capture-mode current-live --interval 5 --retries 0 --retry-delay 0 - env:
HLL_RCON_HISTORICAL_CAPTURE_INTERVAL_SECONDS=5HLL_RCON_CURRENT_MATCH_CAPTURE_INTERVAL_SECONDS=5HLL_RCON_CURRENT_MATCH_MODE=trueHLL_RCON_SKIP_HISTORICAL_MATERIALIZATION=trueHLL_RCON_HISTORICAL_CAPTURE_MAX_RETRIES=0HLL_RCON_HISTORICAL_CAPTURE_RETRY_DELAY_SECONDS=0HLL_RCON_CURRENT_MATCH_WRITER_LOCK_TIMEOUT_SECONDS=4HLL_BACKEND_RCON_ADMIN_LOG_LOOKBACK_MINUTESleft unchanged
Why this is the correct approach:
- TASK-269 added a dedicated worker, but it still competes for the same shared writer lock if the historical worker is left in heavy mode
- the known-good current production behavior already solved current-match freshness with the existing
rcon_historical_workercurrent-livemode - restoring that existing mode is lower-risk than adding a second permanent live worker immediately
- the bad deployment shape is
capture_mode=historicalwithmaterialization_skipped=falseat a near-live cadence, which is the wrong design for current-match freshness - the correct split is:
- current-live worker: fast interval, no heavy materialization, current-match AdminLog freshness
- historical-runner: scheduled heavy historical refresh/snapshot work
Confirmation of protected settings:
- RCON hosts unchanged
- RCON ports unchanged
- RCON credentials unchanged
- server list unchanged
external_server_idvalues unchangedtarget_keyvalues unchanged27001unchangedhistorical-runnercommand and interval unchanged- TASK-269 dedicated worker not activated
Post-deploy validation commands for the operator:
docker inspect -f '{{.Path}} {{json .Args}}' hll-vietnam-rcon-historical-worker-1
docker inspect -f '{{range .Config.Env}}{{println .}}{{end}}' hll-vietnam-rcon-historical-worker-1 | sort | grep -Ei 'CAPTURE|CURRENT|RCON|ADMIN|MATERIAL|INTERVAL|RETRY|LOOKBACK|LOCK'
docker logs --tail=200 hll-vietnam-rcon-historical-worker-1
docker exec -it hll-vietnam-backend-1 sh -lc 'ls -l /app/data/hll_vietnam_dev.writer.lock || true; cat /app/data/hll_vietnam_dev.writer.lock || true'
Expected runtime signals:
- command includes
--capture-mode current-live materialization_skipped=trueinterval_seconds=5retries=0retry_delay=0- targets remain
comunidad-hispana-01andcomunidad-hispana-02 - no repeated heavy materialization every 5 seconds
Current-match API freshness validation script:
cd "D:\Proyectos\HLL Vietnam"
$killsBase = "https://comunidadhll.devzamode.es/api/current-match/kills?server=comunidad-hispana-02&limit=18"
$playersBase = "https://comunidadhll.devzamode.es/api/current-match/players?server=comunidad-hispana-02"
1..18 | ForEach-Object {
$now = Get-Date
$ts = [DateTimeOffset]::UtcNow.ToUnixTimeMilliseconds()
$kills = Invoke-RestMethod "$killsBase&_ts=$ts" -Headers @{ "Cache-Control" = "no-cache"; "Pragma" = "no-cache" }
$killItems = @($kills.data.items)
$topKill = $killItems | Select-Object -First 1
$players = Invoke-RestMethod "$playersBase&_ts=$ts" -Headers @{ "Cache-Control" = "no-cache"; "Pragma" = "no-cache" }
$playerItems = @($players.data.items)
$topPlayers = $playerItems | Sort-Object -Property kills -Descending | Select-Object -First 5 | ForEach-Object {
"$($_.player_name):K=$($_.kills):D=$($_.deaths):Team=$($_.team)"
}
$killLocalTime = ""
$lagSeconds = ""
if ($topKill -and $topKill.server_time) {
$killDate = [DateTimeOffset]::FromUnixTimeSeconds([int64]$topKill.server_time).ToLocalTime()
$killLocalTime = $killDate.ToString("HH:mm:ss")
$lagSeconds = [int](([DateTimeOffset]::Now - $killDate).TotalSeconds)
}
[PSCustomObject]@{
sample = $_
sampled_at = $now.ToString("HH:mm:ss")
kills_scope = $kills.data.scope
kills_count = $killItems.Count
first_id = if ($killItems.Count -gt 0) { $killItems[0].event_id } else { "" }
first_kill_time = $killLocalTime
estimated_lag_seconds = $lagSeconds
first_kill = if ($topKill) { "$($topKill.killer_name)->$($topKill.victim_name):$($topKill.weapon)" } else { "" }
players_count = $playerItems.Count
top_players = ($topPlayers -join " | ")
}
Start-Sleep -Seconds 10
}
Acceptance target:
- when CRCON shows a new kill,
/api/current-match/killsshould advance in roughly5-30seconds /api/current-match/playersshould follow shortly after- not
5-10minutes later
Risks:
- if Portainer stack-level environment variables explicitly override the new current-live env values in a different hidden stack file, runtime may still need operator verification after redeploy
- if another untracked deployment file is actually used instead of
deploy/portainer/docker-compose.nas.yml, the compose change here will not affect the running stack hll-vietnam-backend-1lock-file command assumes the standard container name pattern and may need adaptation if the stack/project name differs
Validation completed:
python -m app.rcon_historical_worker --helpdocker compose -f deploy/portainer/docker-compose.nas.yml --env-file deploy/portainer/stack.env.example configpython -m compileall backend/appcd backend; python -m unittest tests.test_rcon_historical_worker tests.test_current_match_payload- No RCON host changed
- No RCON port changed
- No RCON credentials changed
- No
27001changed - No server list changed
- TASK-269 worker was not activated
Change Budget
- Modified files kept to the requested minimal deployment/docs/task scope.
- No backend Python changes.
- No frontend or asset changes.