6.7 KiB
id, title, status, type, team, supporting_teams, roadmap_item, priority
| id | title | status | type | team | supporting_teams | roadmap_item | priority |
|---|---|---|---|---|---|---|---|
| TASK-228 | Restore near-real-time public server status | done | backend | Backend Senior | foundation | high |
TASK-228 - Restore near-real-time public server status
Goal
Restaurar el comportamiento correcto de la home "Estado actual de servidores" para que /api/servers vuelva a servir estado live o casi-live de los servidores cuando la fuente RCON/A2S este disponible:
- mapa actual
- region/servidor
- jugadores
- estado disponible
La ruta no debe depender exclusivamente de snapshots historicos ni devolver items: [] cuando puede consultar live de forma controlada.
Context
Tras TASK-226, /api/servers respondia rapido pero vacio cuando no existian snapshots:
source: no-snapshot-availablerefresh_attempted: falserefresh_status: cache-onlyitems: []
Eso dejaba la home mostrando "Actualizado no disponible" e "Informacion de servidores disponible mas adelante". Ese resultado no es aceptable para una seccion cuyo contrato es estado actual/casi actual.
Files Read First
ai/architecture-index.mdai/repo-context.mdai/orchestrator/backend-senior.mdbackend/README.mdbackend/app/routes.pybackend/app/payloads.pybackend/app/data_sources.pybackend/app/providers/rcon_provider.pybackend/app/collector.pybackend/tests/test_current_match_payload.py
Call Chain Analysis
Cadena frontend/backend:
- La home usa
frontend/assets/js/main.js. - Ese JS consulta
/api/serverspara renderizar las tarjetas de estado. backend/app/routes.pymapea/api/serversabuild_servers_payload().build_servers_payload()leelist_latest_snapshots()como ultimo estado conocido.- Antes de
TASK-226, si no habia cache o estaba stale, llamaba_try_collect_real_time_snapshot(). _try_collect_real_time_snapshot()usaget_live_data_source().collect_snapshots(...).- Con
HLL_BACKEND_LIVE_DATA_SOURCE=rcon, la fuente efectiva es RCON-first con fallback A2S controlado.
Root Cause
TASK-226 cambio build_servers_payload() a modo cache-only estricto:
- dejo de llamar
_try_collect_real_time_snapshot()desde/api/servers. - marco
refresh_attempted: falsesiempre. - devolvia
items: []cuando no habia snapshot persistido.
Ese cambio arreglo latencia de request, pero rompio el contrato funcional de la home cuando no hay cache caliente.
Changes
backend/app/payloads.py- Restaura la politica near-real-time:
- si hay snapshot fresco, sirve cache sin refresh.
- si no hay snapshot o esta stale, intenta refresh live.
- si live devuelve items, responde con
real-time-rcon-refresh,real-time-a2s-fallbacko equivalente. - si live falla, devuelve snapshot stale si existe.
- si live falla y no hay snapshot, responde
items: []con error controlado y metadata de fallback.
_try_collect_real_time_snapshot()captura excepciones y evita 500.- El refresh publico usa timeout interno corto
PUBLIC_SERVER_STATUS_TIMEOUT_SECONDS = 2.5sin cambiar variables de entorno ni configuracion RCON.
- Restaura la politica near-real-time:
backend/app/data_sources.py- Extiende el contrato live para aceptar
timeout_secondsopcional. - Propaga ese timeout a RCON-first y A2S cuando la llamada publica lo solicita.
- Extiende el contrato live para aceptar
backend/app/providers/rcon_provider.py- Propaga
timeout_secondsopcional aquery_live_server_sample(). - Las llamadas que no pasan timeout siguen usando
HLL_BACKEND_RCON_TIMEOUT_SECONDS.
- Propaga
backend/tests/test_current_match_payload.py- Ajusta el test de
/api/serversdecache-onlya near-real-time. - Cubre refresh live cuando no hay cache.
- Cubre respuesta controlada si live falla sin cache.
- Cubre fallback a snapshot stale si live falla con cache existente.
- Ajusta el test de
docs/FULL_APPLICATION_REQUEST_AUDIT.md- Documenta el estado post-fix de
TASK-228.
- Documenta el estado post-fix de
docs/PERFORMANCE_PUBLIC_QUERY_AUDIT.md- Actualiza
/api/serverscomo near-real-time controlado en vez de cache-only.
- Actualiza
Validation
Validaciones ejecutadas:
python -m compileall backend/app
cd backend
python -m unittest tests.test_current_match_payload
python -m unittest tests.test_current_match_payload tests.test_rcon_admin_log_storage tests.test_historical_snapshot_refresh
Resultados:
python -m compileall backend/app: OK.cd backend; python -m unittest tests.test_current_match_payload: OK, 7 tests.cd backend; python -m unittest tests.test_current_match_payload tests.test_rcon_admin_log_storage tests.test_historical_snapshot_refresh: OK, 20 tests.
Auditoria local:
- No se ejecuto porque
http://127.0.0.1:8000/healthno respondio desde el host.
Comandos de validacion de produccion tras redeploy:
$base = "https://comunidadhll.devzamode.es"
Invoke-WebRequest "$base/api/servers" |
Select-Object -ExpandProperty Content
Invoke-WebRequest "$base/api/servers/latest" |
Select-Object -ExpandProperty Content
Invoke-WebRequest "$base/api/servers/history" |
Select-Object -ExpandProperty Content
python .\scripts\audit_public_requests.py --base-url https://comunidadhll.devzamode.es --timeout 30 --filter servers --output tmp\task228_servers_audit_after.json
Outcome
/api/servers vuelve a intentar estado live/casi-live de forma controlada cuando no hay cache o el cache esta vencido. Si RCON/A2S responde, la home recibe items reales. Si RCON/A2S no responde en el entorno de pruebas, el endpoint devuelve JSON controlado y no debe bloquear 30 s ni devolver 500 vacio.
Constraints Confirmed
- No se cambio
27001. - No se cambiaron hosts ni puertos RCON.
- No se cambio
127.0.0.1. - No se cambiaron variables de entorno de servidores.
- No se cambio configuracion de servidores.
- No se tocaron player search/profile/historical detail.
- No se tocaron current-match/kills ni current-match/players salvo por tests compartidos.
- No se reactivo Elo/MMR.
- No se reintrodujo Comunidad Hispana #03.
- No se toco frontend.
- No se tocaron assets, SVGs ni imagenes fisicas.
- No se toco
frontend/assets/img/weapons/. - No se toco
frontend/assets/img/clans/. - No se toco
ai/system-metrics.md. - No se incluyo
tmp/.
Risks
- El refresh live sigue siendo sincronico y consulta targets configurados. El timeout publico corto reduce el riesgo de 30 s, pero con varios targets o un servidor que responde parcialmente puede haber latencia acumulada.
- No se persiste el snapshot live desde el GET publico para evitar DDL/inicializaciones pesadas en la lectura publica.
/api/servers/latesty/api/servers/historypueden seguir vacios hasta que un proceso de captura/persistencia actualice almacenamiento. - La validacion final de que la home muestra servidores requiere redeploy en el entorno donde RCON/live este disponible.