CreaRack-SL

Agent 2.16.0 — Throttle del resync histórico + diagnóstico del flapping WS + aviso de portátil

Resumen

La versión 2.16.0 del Local Agent resuelve un bucle vicioso de amplificación de datos: cuando la conexión WebSocket con el servidor se vuelve inestable (flapping), el Agente re-enviaba las 24 horas completas de métricas en CADA reconexión, lo que a su vez sobrecargaba la red y tumba la conexión nuevamente (22× de amplificación documentada en YogaEdu, 21-07-2026). Esta release implementa:

  1. Throttle del backfill histórico (#203): solo se re-arma tras un corte real (≥10 min) y solo el hueco faltante, no 24h.
  2. Instrumentación del cierre WS (#203): los close_code y la duración de cada sesión se loguean y exponen en /info (antes invisible).
  3. Aviso de portátil desde el día 1 (#197): el Agente reporta si vive en una máquina con batería (psutil.sensors_battery) → el aviso del Sentinel 24/7 salta inmediatamente.
  4. Bump de seguridad: websockets 15.0.1 → 16.1.1 en el lock (solo instalaciones frescas).

Problema diagnosticado (22-07-2026, en vivo)

Síntomas observados

  • Flapping del WS: YogaEdu, ~3.539 reconexiones el 21-07, duración por sesión ~6,6s.
  • Círculo vicioso: cada reconexión armaba un push_historical(24h) de 5.000 métricas (~33-39s por batch) → la conexión solo duraba 6,6s → resync sin fin.
  • Amplificación: el bombardeo de datos ayudaba a tumbar la propia conexión (causa probable: saturación uplink + event loop/storage).
  • Punto ciego de observabilidad: el close_code y las stats de reconexión no se exponían en ninguna ruta.

Datos de diagnostico

  • Agente: agent_ca6ba7b2364f (Edu, YogaEdu, v2.15.1 onedir, 131 targets, metrics.db 197 MB).
  • Correlación server-side: cada WSDISCONNECT llegaba justo tras un bulk POST de 1000 métricas.
  • Query: SELECT COUNT(*) FROM agent_log WHERE created_at > '2026-07-21' AND level='WSRECONNECT' → 3.539 en 24h (único incident en la flota).

Cambios técnicos

#203 · Throttle del resync + Instrumentación

terminal/agent/core/sync.py:

  • Registra _disconnected_at en on_disconnected().
  • En reconexión, distingue:
    • Downtime < 10 min (criterio DISCONNECT_GAP_MINUTES = 600): NO resync histórico. El flujo normal (push_unsynced()) cubre las filas pendientes.
    • Downtime ≥ 10 min: resync SOLO del hueco real = (downtime + margen 15 min, cap 24h).
    • Cooldown 15 min: mínimo tiempo entre resyncs completados.
  • Primer backfill tras arranque sigue siendo completo (alimenta Observatory/gráficas).
  • Guard server-side v1.61.2 actúa como segunda línea de defensa.

terminal/agent/core/connector.py:

  • Loguea close_code, motivo y duración al salir del receive loop.
  • Expone stats en /info sección saas.ws:
    • reconnect_count: contador global desde arranque.
    • last_close_code: código HTTP/WS del último cierre.
    • last_session_secs: segundos de la última sesión.
    • last_error: string del último error registrado (si aplica).

#197 · Aviso de portátil

terminal/agent/core/agent_status.py:

  • Agrega campo has_battery = psutil.sensors_battery() (psutil ya empaquetado desde v2.13.2).
  • Registra en BD: migración terminal_0005 añade AgentInstance.has_battery (NULL para agents viejos).
  • Consumidor SaaS la persiste en agent_status.

static/js/pages/observatory/ObservatorySentinel.js:

  • En _primaryStabilityWarning(), si primary.has_battery === true, salta el aviso de portátil desde el día 1 (antes solo saltaba tras ≥3 cortes largos en 7 días, v1.49.0).
  • i18n ES incluida en djangojs.po.

#196 · Bump websockets

  • terminal/agent/requirements-agent.lock: websockets 15.0.1 → 16.1.1.
  • Sin CVE. Límite honesto: flota existente se actualiza por paquete de código, NO recibe la lib (queda en 15, sin riesgo). Solo instalaciones frescas del Setup.exe llevan 16.

Verificación post-deploy

  1. KPI resync: reconexiones/h en YogaEdu deben caer a ~0 (normal background reconexiones por red office/VPN).
  2. close_code logs: si WS sigue cayendo, los logs dirán quién corta (Cloudflare / Daphne / red).
  3. Batería: portal Sentinel detecta portátiles desde activation day 1.

Releases

  • Agent: v2.16.0 (bump terminal/agent/version.py).
  • SaaS: v1.62.0 (migración terminal_0005, campos model has_battery, i18n).

Tasks asociadas

  • #203: Throttle del resync + instrumentación WS → merged 22-07-2026 11:04 UTC.
  • #196: Bump websockets → merged 22-07-2026 11:04 UTC.
  • #197: has_battery + aviso portátil → merged 22-07-2026 11:04 UTC.

Véase también

  • [[entity—terminal—service—sync-throttle]]
  • [[entity—terminal—service—connector-ws-diagnostics]]
  • [[entity—terminal—model—agent-instance]]
  • [[concept—infra—agent-health-monitoring]]
  • [[concept—saas—high-availability]]