Errori del database memorizzati nella cache per 30 minuti in client_settings_json - il sito non si carica

Priorità/Gravità: Raro ma critico
Il sito diventa inutilizzabile per un massimo di 30 minuti dopo errori transitori del database. Le pagine non vengono caricate correttamente a causa di impostazioni client mancanti che causano errori JavaScript.

Piattaforma:

  • Interessa: Tutte le installazioni di Discourse
  • Osservato in: Ambienti di produzione che sperimentano problemi transitori di connettività del database

Descrizione

Risultato Effettivo
Quando si verifica un errore transitorio del database (timeout della connessione, esaurimento del pool, glitch di rete), l’errore viene memorizzato nella cache per 30 minuti. Durante questo periodo:

  • Il sito non viene caricato correttamente: le pagine appaiono danneggiate o non funzionanti
  • Si verificano errori JavaScript lato client a causa di impostazioni mancanti/non valide
  • Ogni richiesta registra “Nil client_settings_json from the cache for ‘client_settings_json\[git_version\]’”
  • Vengono restituite al browser impostazioni client vuote
  • Ciò continua anche dopo che il database si è completamente ripristinato

Risultato Atteso
Quando si verifica un errore transitorio del database, il sistema non dovrebbe memorizzare nella cache l’errore. Una volta che il database si ripristina, la richiesta successiva dovrebbe recuperare e memorizzare nella cache correttamente le impostazioni client e il sito dovrebbe riprendere il normale funzionamento immediatamente.

Passaggi Riproducibili

  1. Avviare un’istanza Discourse con impostazioni client configurate
  2. Simulare un problema di connettività del database (ad es. esaurire il pool di connessioni, introdurre un ritardo di rete o bloccare temporaneamente la porta 5432)
  3. Effettuare una richiesta che attivi SiteSetting.client_settings_json (qualsiasi caricamento di pagina lo farà)
  4. Osservare l’errore: “Error while generating client_settings_json_uncached: [database error]”
  5. Le pagine non vengono renderizzate correttamente, la console JavaScript mostra errori relativi a impostazioni mancanti
  6. Ripristinare la connettività del database
  7. Effettuare richieste aggiuntive nei successivi 30 minuti. Continuare a vedere errori “Nil client_settings_json from the cache” nonostante il database sia integro
  8. Dopo 30 minuti, la cache scade e il sito si ripristina finalmente

Impatto sull’Utente

Il sito è effettivamente inattivo durante questo periodo:

  • Le pagine non vengono renderizzate correttamente
  • Le applicazioni JavaScript non si inizializzano a causa della configurazione mancante

Ciò trasforma un singhiozzo del database di 1 secondo in un’interruzione di 30 minuti.

Causa Principale

In lib/site_setting_extension.rb, il metodo client_settings_json_uncached cattura le eccezioni e restituisce nil. Questo nil viene memorizzato nella cache per 30 minuti, danneggiando il sito.

Correzione Proposta

È stata inviata una pull request per risolvere questo problema. La correzione richiede una semplice modifica per ri-sollevare l’eccezione invece di restituire nil.

Perché funziona:

  1. Ri-sollevare l’eccezione impedisce a Discourse.cache.fetch di memorizzare nella cache l’errore
  2. Il metodo esterno client_settings_json ha già una gestione delle eccezioni adeguata che restituisce “” (stringa vuota) senza memorizzarla nella cache
  3. Il sito può continuare a funzionare durante i problemi del database (sebbene degradato)
  4. Il sito si ripristina automaticamente alla richiesta successiva una volta che il database è integro
  5. La correzione garantisce che gli errori transitori del database non causino interruzioni di 30 minuti.

Impatto

Questo bug interessa tutte le installazioni di Discourse che sperimentano problemi transitori del database:

  • Esaurimento del pool di connessioni durante picchi di traffico
  • Glitch di rete tra l’applicazione e il database
  • Scenari di failover del database (ad es. switchover primario/replica)
  • Contesa di lock sulla tabella site_settings
  • Timeout delle query a causa di query lente

Gravità: Qualsiasi di questi problemi comuni e transitori causa l’inutilizzabilità dell’intero sito per 30 minuti, anche se il problema sottostante si risolve in pochi secondi.

Soluzione Alternativa

Se stai riscontrando questo problema in questo momento, puoi cancellare manualmente la cache per ripristinare il servizio:

Nella console Rails

Discourse.cache.delete(SiteSettingExtension.client_settings_cache_key)
2 Mi Piace

Ottima osservazione, lavorerò a una soluzione per questo.

5 Mi Piace

sembra che sia stato unito, grazie mille.

2 Mi Piace