CreaRack-SL

Observatory pedía la matriz de disponibilidad 21 veces en 13s con la vista general oculta

Cuándo

Visto en PROD tras el despliegue de la v1.161.0 (24-09-2026). Corregido al día siguiente, 25-09-2026, dentro de la ronda 7 de la mega-auditoría (commit 1ac8bf96, PR #610, publicado en v1.162.0).

Síntomas visibles

Con la página del Observatory abierta y la pestaña de un equipo concreto delante (es decir, con la vista general — la que pinta la matriz de disponibilidad de 24h — oculta detrás), la función loadAvailabilityHeatmap repetía su petición a /availability-heatmap (una respuesta de 62 KB) en cada reintento de su segunda cadena de reintentos por setTimeout: 21 llamadas a la API en 13 segundos, todas mientras el usuario ni siquiera estaba mirando esa vista.

Causa raíz

La función esperaba a que el contenedor de la gráfica tuviera un tamaño real antes de dibujar, pero esa espera vivía en una capa aparte de la llamada a la API: cada reintento de la cadena volvía a pedir los datos a la API aunque el contenedor siguiera oculto (tamaño cero), en vez de comprobar primero si tenía sentido pedir nada.

Fix aplicado

loadAvailabilityHeatmap (en static/js/pages/observatory/ObservatoryOverview.js / ObservatoryCharts.js) ahora espera el tamaño dentro de su propia promesa, sin llamar a la API mientras el contenedor está oculto. Si sigue oculta cuando se agota esa espera, la gráfica la dibuja el observador de tamaño del widget en el momento en que el usuario vuelve a esa pestaña — una sola vez, no en bucle.

Verificado con test: antes de la corrección, 21 llamadas a la API en 13 segundos con la vista oculta; después, 0 llamadas mientras está oculta y exactamente 1 al volver a mostrarla.

Lecciones

Un reintento por setTimeout que no comprueba el estado real (aquí, visibilidad/tamaño del contenedor) antes de repetir la llamada puede multiplicarse en silencio — no lanza ningún error, solo repite tráfico. La espera de una condición externa (que el contenedor tenga tamaño) tiene que vivir dentro de la misma promesa que ya se reintenta, no en una capa envolvente que no sabe si el reintento interior ya está en marcha.

Preventivos futuros

El test que verifica “0 llamadas ocultas, 1 llamada al volver” queda como regresión permanente contra este patrón concreto.

Véase también

  • [[feature—monitoring—dashboard-customize]]
  • [[concept—workspace—incidents-index]]