Errores de base de datos almacenados en caché durante 30 minutos en client_settings_json - El sitio no se carga

Prioridad/Severidad: Raro pero crítico
El sitio se vuelve inutilizable hasta por 30 minutos después de errores transitorios de la base de datos. Las páginas no se cargan correctamente debido a la falta de configuraciones del cliente, lo que provoca errores de JavaScript.

Plataforma:

  • Afecta: Todas las instalaciones de Discourse
  • Observado en: Entornos de producción que experimentan problemas transitorios de conectividad con la base de datos

Descripción

Resultado Actual
Cuando ocurre un error transitorio en la base de datos (tiempo de espera de conexión, agotamiento del pool, glitch de red), el error se almacena en caché durante 30 minutos. Durante este tiempo:

  • El sitio no se carga correctamente: las páginas aparecen rotas o no funcionales.
  • Ocurren errores de JavaScript del lado del cliente debido a configuraciones faltantes/inválidas.
  • Cada solicitud registra “Nil client_settings_json from the cache for ‘client_settings_json\[git_version\]’”
  • Se devuelven configuraciones de cliente vacías al navegador.
  • Esto continúa incluso después de que la base de datos se haya recuperado por completo.

Resultado Esperado
Cuando ocurre un error transitorio en la base de datos, el sistema no debe almacenar el error en caché. Una vez que la base de datos se recupera, la siguiente solicitud debe obtener y almacenar en caché correctamente la configuración del cliente, y el sitio debe reanudar su funcionamiento normal de inmediato.

Pasos para Reproducir

  1. Inicie una instancia de Discourse con la configuración del cliente configurada.
  2. Simule un problema de conectividad de la base de datos (por ejemplo, agote el pool de conexiones, introduzca un retraso de red o bloquee temporalmente el puerto 5432).
  3. Realice una solicitud que active SiteSetting.client_settings_json (cualquier carga de página lo hará).
  4. Observe el error: “Error while generating client_settings_json_uncached: [database error]”
  5. Las páginas no se renderizan correctamente, la consola de JavaScript muestra errores relacionados con la falta de configuraciones.
  6. Restaure la conectividad de la base de datos.
  7. Realice solicitudes adicionales durante los próximos 30 minutos. Continúe viendo errores de “Nil client_settings_json from the cache” a pesar de que la base de datos funciona correctamente.
  8. Después de 30 minutos, la caché expira y el sitio finalmente se recupera.

Impacto en el Usuario

El sitio está efectivamente caído durante este período:

  • Las páginas no se renderizan correctamente.
  • Las aplicaciones JavaScript fallan al inicializarse debido a la falta de configuración.

Esto convierte un hipo de base de datos de 1 segundo en una interrupción de 30 minutos.

Causa Raíz

En lib/site_setting_extension.rb, el método client_settings_json_uncached captura excepciones y devuelve nil. Este nil se almacena en caché durante 30 minutos, lo que rompe el sitio.

Solución Propuesta

Se ha enviado una pull request para solucionar este problema. La solución requiere un cambio simple para volver a lanzar la excepción en lugar de devolver nil.

Por qué funciona:

  1. Volver a lanzar la excepción evita que Discourse.cache.fetch almacene el error en caché.
  2. El método externo client_settings_json ya tiene un manejo de excepciones adecuado que devuelve “” (cadena vacía) sin almacenarlo en caché.
  3. El sitio puede continuar funcionando durante los problemas de la base de datos (aunque degradado).
  4. El sitio se recupera automáticamente en la siguiente solicitud una vez que la base de datos funciona correctamente.
  5. La solución garantiza que los errores transitorios de la base de datos no causen interrupciones de 30 minutos.

Impacto

Este error afecta a todas las instalaciones de Discourse que experimentan problemas transitorios con la base de datos:

  • Agotamiento del pool de conexiones durante picos de tráfico.
  • Glitch de red entre la aplicación y la base de datos.
  • Escenarios de conmutación por error de la base de datos (por ejemplo, cambio entre primario/réplica).
  • Contención de bloqueo en la tabla site_settings.
  • Tiempos de espera de consulta debido a consultas lentas.

Severidad: Cualquiera de estos problemas comunes y transitorios hace que todo el sitio quede inutilizable durante 30 minutos, incluso si el problema subyacente se resuelve en segundos.

Solución Alternativa

Si está experimentando este problema ahora mismo, puede borrar manualmente la caché para restaurar el servicio:

En la consola de Rails

Discourse.cache.delete(SiteSettingExtension.client_settings_cache_key)
2 Me gusta

Gran hallazgo, trabajaré en una solución para esto.

5 Me gusta

Parece que se fusionó, muchas gracias.

2 Me gusta