Erreurs de base de données mises en cache pendant 30 minutes dans client_settings_json - Le site ne se charge pas

Priorité/Gravité : Rare mais critique
Le site devient inutilisable pendant 30 minutes après des erreurs de base de données transitoires. Les pages ne se chargent pas correctement en raison de paramètres client manquants qui provoquent des erreurs JavaScript.

Plateforme :

  • Affecte : Toutes les installations Discourse
  • Observé dans : Environnements de production connaissant des problèmes de connectivité de base de données transitoires

Description

Résultat actuel
Lorsqu’une erreur de base de données transitoire se produit (délai d’attente de connexion, épuisement du pool, problème réseau), l’erreur est mise en cache pendant 30 minutes. Pendant ce temps :

  • Le site ne se charge pas correctement : les pages apparaissent cassées ou non fonctionnelles
  • Des erreurs JavaScript côté client se produisent en raison de paramètres manquants/invalides
  • Chaque requête enregistre « Nil client_settings_json from the cache for ‘client_settings_json\[git_version\]’ »
  • Des paramètres client vides sont renvoyés au navigateur
  • Cela continue même après que la base de données a complètement récupéré

Résultat attendu
Lorsqu’une erreur de base de données transitoire se produit, le système ne doit pas mettre l’erreur en cache. Une fois la base de données récupérée, la prochaine requête doit récupérer et mettre en cache avec succès les paramètres client, et le site doit reprendre son fonctionnement normal immédiatement.

Étapes reproductibles

  1. Démarrer une instance Discourse avec des paramètres client configurés
  2. Simuler un problème de connectivité de base de données (par exemple, épuiser le pool de connexions, introduire un délai réseau ou bloquer temporairement le port 5432)
  3. Effectuer une requête qui déclenche SiteSetting.client_settings_json (n’importe quel chargement de page le fera)
  4. Observer l’erreur : « Error while generating client_settings_json_uncached: \[database error\] »
  5. Les pages ne se rendent pas correctement, la console JavaScript affiche des erreurs liées à des paramètres manquants
  6. Restaurer la connectivité de la base de données
  7. Effectuer des requêtes supplémentaires pendant les 30 minutes suivantes. Continuer à voir des erreurs « Nil client_settings_json from the cache » malgré une base de données saine
  8. Après 30 minutes, le cache expire et le site récupère enfin

Impact utilisateur

Le site est effectivement en panne pendant cette période :

  • Les pages ne se rendent pas correctement
  • Les applications JavaScript ne s’initialisent pas en raison d’une configuration manquante

Cela transforme un problème de base de données de 1 seconde en une panne de 30 minutes.

Cause racine

Dans lib/site_setting_extension.rb, la méthode client_settings_json_uncached (discourse/lib/site_setting_extension.rb at main · discourse/discourse · GitHub) intercepte les exceptions et renvoie nil (discourse/lib/site_setting_extension.rb at main · discourse/discourse · GitHub). Ce nil est mis en cache pendant 30 minutes, ce qui casse le site.

Correction proposée

Une pull request a été soumise pour corriger ce problème. La correction nécessite une simple modification pour relancer l’exception au lieu de renvoyer nil.

Pourquoi ça marche :

  1. Relancer l’exception empêche Discourse.cache.fetch de mettre l’erreur en cache
  2. La méthode externe client_settings_json gère déjà correctement les exceptions, renvoyant une chaîne vide ("") sans la mettre en cache
  3. Le site peut continuer à fonctionner pendant les problèmes de base de données (bien que dégradé)
  4. Le site récupère automatiquement à la prochaine requête une fois la base de données saine
  5. La correction garantit que les erreurs de base de données transitoires ne provoquent pas de pannes de 30 minutes.

Impact

Ce bug affecte toutes les installations Discourse rencontrant des problèmes de base de données transitoires :

  • Épuisement du pool de connexions lors des pics de trafic
  • Problèmes réseau entre l’application et la base de données
  • Scénarios de basculement de base de données (par exemple, basculement maître/réplique)
  • Contention de verrouillage sur la table site_settings
  • Dépassements de délai d’attente des requêtes en raison de requêtes lentes

Gravité : N’importe lequel de ces problèmes courants et transitoires rend le site entier inutilisable pendant 30 minutes, même si le problème sous-jacent se résout en quelques secondes.

Solution de contournement

Si vous rencontrez ce problème actuellement, vous pouvez vider manuellement le cache pour rétablir le service :

Dans la console Rails

Discourse.cache.delete(SiteSettingExtension.client_settings_cache_key)
2 « J'aime »

Excellente trouvaille, je vais travailler sur une solution pour cela.

5 « J'aime »

On dirait que ça a été fusionné, merci beaucoup.

2 « J'aime »