Cache di GLPI: perché la sua modifica non compare a schermo

GLPI mantiene tre cache distinte e i pulsanti di svuotamento compaiono solo in modalità debug. Scopra quale svuotare per ogni sintomo, su GLPI 10, 11 e 12.

Ha aggiornato un plugin, corretto una traduzione o modificato un'impostazione, e la schermata rimane identica. Nella maggior parte dei casi il problema non è ciò che ha cambiato, ma la cache di GLPI, che continua a servire la versione precedente.

GLPI non ha "una cache". Ne ha tre.

Questo è il primo punto che genera confusione. Quando si dice "svuota la cache di GLPI", dietro ci sono tre cose diverse, con finalità distinte, e svuotare quella sbagliata non risolve nulla:

  • Cache opcode (PHP): conserva il bytecode dei file .php già compilati, affinché PHP non reinterpreti il codice a ogni richiesta. È l'estensione Zend OPcache, di PHP stesso, non di GLPI.
  • Cache dei dati utente: conserva dati dell'applicazione, come impostazioni ed elenchi che GLPI consulta di continuo. Internamente GLPI chiama questo contesto core, e può risiedere su disco oppure in Redis/Memcached.
  • Cache delle traduzioni: conserva i cataloghi di lingua già elaborati, affinché GLPI non legga i file .mo a ogni schermata. È la responsabile del sintomo più frequente, il testo che resta nella lingua precedente.

La regola pratica: se ciò che è cambiato è codice, il sospettato è l'opcode. Se è testo dell'interfaccia, è quella delle traduzioni. Se è configurazione o dato, è quella dei dati utente.

Dove si trovano questi file

La cache su disco di GLPI risiede nella cartella dei file dell'installazione, sotto files/_cache/. Al suo interno troverà una directory con un nome simile a questo:

files/_cache/11.0.7-49a93008-production/
    app/
    templates/
    translations/

Un avvertimento su queste tre cartelle: non corrispondono una a una alle tre cache mostrate a schermo. La cartella translations contiene effettivamente i cataloghi di lingua, ma app è la cache interna del framework (contenitore di iniezione delle dipendenze, annotazioni), non la cache dei dati utente. E se l'ambiente è configurato con Redis o Memcached, i dati utente non si trovano affatto in quella directory: risiedono nel servizio esterno, mentre la cartella su disco continua a esistere con la cache del framework. Cercare lì, in quel caso, porta nel posto sbagliato.

Osservi il nome della cartella: contiene la versione di GLPI, un hash e l'ambiente. Questo ha una conseguenza pratica poco nota: aggiornando GLPI, lo spazio dei nomi cambia e la vecchia cache smette di essere consultata da sola. Per questo un aggiornamento di versione soffre raramente di cache obsoleta, mentre l'aggiornamento di un plugin, che non cambia la versione di GLPI, ne soffre spesso.

Attenzione se utilizza GLPI 10: questa organizzazione in un'unica directory versionata appartiene alla linea 11 e 12, che si basano sul Kernel di Symfony. In GLPI 10 lo stesso files/_cache ha un'altra struttura, con cartelle separate e senza suffisso di ambiente:

files/_cache/core/
files/_cache/templates/
files/_cache/installer-10.0.24/
files/_cache/translations-10.0.24/

Noti che lì soltanto l'installatore e le traduzioni riportano la versione nel nome, e le versioni precedenti si accumulano: è comune trovare una mezza dozzina di translations-10.0.x di aggiornamenti passati. I percorsi cambiano, ma il ragionamento di questo articolo resta lo stesso, e sia i pulsanti dell'interfaccia sia il comando da console funzionano allo stesso modo.

Anche i plugin usano quella directory. In un'installazione con NexTool, per esempio, vi convivono file come nextool_boot_manifest.cache e voci per modulo, ciascuna con la propria strategia di invalidazione.

Disco o Redis: dove si trova davvero la sua cache

La cache dei dati utente e quella delle traduzioni non sono necessariamente su disco. GLPI consente di indirizzarle verso Redis o Memcached, e la schermata Prestazioni indica essa stessa quale sistema è in uso, con una riga del tipo "L'estensione di cache redis è installata" oppure "Il sistema di cache filesystem è in uso".

Questo cambia la diagnosi in due scenari frequenti. In un'installazione con più di un server applicativo dietro un bilanciatore, una cache su disco significa una cache per server: svuotarla su un nodo non la svuota sugli altri, e l'utente vede il contenuto vecchio o nuovo a seconda di dove è arrivata la richiesta. Con un Redis condiviso, invece, un solo svuotamento vale per tutti.

L'altro scenario è il container. Se la cache è su disco all'interno del container e non in un volume, ricreare il container svuota la cache di conseguenza, il che a volte "risolve" il problema per caso e nasconde la causa reale.

Per verificare o modificare la configurazione da riga di comando:

php bin/console cache:configure

Anche i plugin hanno una cache

Oltre alle tre cache del nucleo, ogni plugin può mantenere la propria. GLPI offre un contesto dedicato per plugin, ed è per questo che il comando di svuotamento accetta --context=plugin:nome_del_plugin.

Una precisazione: quel contesto esiste solo se il plugin utilizza l'API di cache di GLPI. Molti plugin mantengono la propria cache in file separati, al di fuori di quel meccanismo, e in tali casi --context=plugin:nome non ha alcun effetto su di essi. Se dopo aver svuotato tutto il comportamento persiste, cerchi i file di cache propri del plugin nella directory files/_cache.

In pratica questo significa che un comportamento anomalo dopo l'aggiornamento di un plugin non si risolve sempre svuotando le cache di GLPI: può essere necessario svuotare il contesto di quel plugin in particolare. I plugin con molti moduli tendono a conservare in cache manifesti di avvio e schemi, proprio per non ricalcolare tutto a ogni richiesta, ed è quel file a diventare obsoleto dopo un cambio di versione.

Perché i pulsanti di svuotamento non compaiono

Ecco il dettaglio che porta molti a concludere che l'opzione non esista nella propria versione. La schermata c'è, i blocchi ci sono, eppure non c'è alcun pulsante da premere.

Il motivo è che i pulsanti di svuotamento vengono mostrati solo quando l'utente è in modalità debug. Nel codice di GLPI 11 ciascuno dei tre blocchi si trova all'interno di una condizione che verifica la modalità della sessione. In modalità normale la schermata mostra la diagnosi, la memoria, il tasso di successo, l'estensione in uso, ma non offre l'azione.

In altre parole: non sono i permessi, non è la versione, non è un difetto. È la modalità della sessione.

Come attivare la modalità debug

La modalità si trova nel profilo dell'utente, non in un'impostazione globale:

  1. Clicchi sul suo nome, in alto a destra, e apra le Preferenze.
  2. Individui il campo Utilizzare GLPI in modalità.
  3. Passi da Normale a Debug e salvi.
Schermata delle preferenze di GLPI con il campo Utilizzare GLPI in modalità evidenziato, dove si passa da Normale a Debug
Il campo si trova al centro delle preferenze dell'utente, subito sotto la lingua, e compare solo per i profili amministrativi.

Due osservazioni importanti. La prima: quel campo compare soltanto per chi ha un profilo di amministratore. Se non lo trova, la strada è chiederlo a un amministratore dell'ambiente. La seconda: la modalità debug fa sì che GLPI mostri informazioni tecniche in diverse schermate e aggiunge un sovraccarico di elaborazione. Torni alla modalità Normale appena finito, soprattutto in produzione.

Svuotare dall'interfaccia

Con la modalità debug attiva, vada in Configurazione > Generale e apra la scheda Prestazioni. I tre blocchi mostrano ora ciascuno il proprio pulsante di svuotamento, e ognuno svuota soltanto la propria cache.

Se dopo aver salvato la preferenza i pulsanti ancora non compaiono, ricarichi la pagina di configurazione. La scheda delle prestazioni carica il contenuto in modo asincrono, e potrebbe essere stata generata prima del cambio di modalità.

Scheda Prestazioni di GLPI che mostra i tre blocchi di cache, ciascuno con il proprio pulsante di svuotamento
Con la modalità debug attiva, ogni blocco ottiene il proprio pulsante di svuotamento.

Svuoti solo il blocco corrispondente al suo sintomo. Svuotare tutti e tre "per sicurezza" è un'abitudine costosa: eliminare la cache opcode obbliga PHP a ricompilare l'intera applicazione nelle richieste successive, e in un ambiente con utenti attivi questo si manifesta come lentezza per alcuni minuti.

Svuotare da riga di comando

Chi ha accesso al server dispone di una via più diretta, che non richiede né la modalità debug né il passaggio dall'interfaccia. Dalla radice dell'installazione di GLPI:

# svuota tutti i contesti di cache
php bin/console cache:clear

Il comando accetta di restringere l'ambito, cosa preferibile in produzione per lo stesso motivo indicato sopra:

# svuota solo la cache delle traduzioni, il caso più comune
php bin/console cache:clear --context=translations

# svuota solo i dati utente
php bin/console cache:clear --context=core

# svuota la cache di un plugin specifico
php bin/console cache:clear --context=plugin:nome_del_plugin

Una precauzione che evita grattacapi: esegua il comando con lo stesso utente che esegue il server web (normalmente www-data o apache). Eseguirlo come root ricrea file di cache di proprietà di root, il server web non riesce più a scrivervi, e un problema temporaneo diventa permanente.

Da notare che cache:clear agisce sulle cache gestite da GLPI. La cache opcode di PHP appartiene all'estensione stessa, e viene reimpostata al ricaricamento del servizio PHP-FPM.

Quale svuotare per ciascun sintomo

Che cosa succedeCache da svuotare
Il testo resta nella lingua precedente dopo l'aggiornamento di un pluginTraduzioni
Una nuova traduzione aggiunta non compareTraduzioni
Una modifica in un file .php non ha effettoOpcode (PHP)
Impostazione salvata ma la schermata mostra il valore precedenteDati utente
Menu o voce di plugin che non scompare dopo la disinstallazioneDati utente

E in GLPI 12?

Confrontando il codice delle due versioni, il metodo descritto qui resta pienamente valido in GLPI 12: le stesse tre cache, gli stessi contesti core e translations, la stessa necessità della modalità debug perché i pulsanti compaiano, e lo stesso comando da console. La directory su disco segue lo schema della linea 11, con la versione nel nome, come in files/_cache/12.0.0-rc1-08464f22-production/.

Due differenze meritano l'attenzione di chi amministra ambienti con molti plugin.

La prima riguarda la memoria. In GLPI 12 lo svuotamento della cache salta ora la precompilazione dei template, con una motivazione esplicita nel codice stesso: i template sono più di 400, e riscaldarli tutti insieme superava il limite di memoria predefinito di PHP. Al loro posto, ogni template viene compilato la prima volta che la pagina viene aperta. In pratica questo rende lo svuotamento più leggero e affidabile, ma sposta il costo su chi apre per primo ciascuna schermata dopo l'operazione.

La seconda riguarda i plugin. In GLPI 12, attivare, disattivare o installare un plugin qualsiasi svuota ora l'intera cache dei template compilati, non solo quella di quel plugin. Il codice stesso registra il limite, con una nota che chiede di separare in futuro la cache per spazio dei nomi. L'effetto collaterale è che, in un ambiente ricco di moduli, toccare un singolo plugin fa ricompilare tutti i template su richiesta in seguito. Nulla si rompe, ma le prime aperture delle schermate risultano più lente.

Il caso che inganna: metà schermata tradotta

Esiste una situazione in cui la cache delle traduzioni inganna anche chi conosce bene il sistema. La schermata si apre con una parte dei testi nella lingua corretta e una parte nella lingua originale, mescolati, a volte in campi vicini. La conclusione naturale è che la traduzione del plugin sia incompleta.

Quasi sempre non lo è. Quando un plugin si aggiorna da solo e sovrascrive i propri file, deve invalidare due cache, non una: quella opcode, perché PHP esegua il nuovo codice, e quella delle traduzioni, perché GLPI rilegga i cataloghi. Invalidare solo la prima produce esattamente quel risultato: le stringhe già esistenti continuano a essere servite dalla cache, tradotte, mentre le nuove stringhe di quella versione non sono ancora nel catalogo in memoria e compaiono nella lingua di origine.

Ciò che smaschera il caso è proprio la mescolanza. Una traduzione davvero incompleta tende a lasciare interi blocchi nella lingua originale, seguendo la struttura del file di traduzione. Una cache obsoleta lascia il testo vecchio tradotto e quello nuovo no, senza logica apparente, perché la divisione non è per schermata: è secondo ciò che era già in memoria.

La conferma è semplice: svuoti la cache delle traduzioni e ricarichi. Se la schermata diventa coerente, era la cache. Se la mescolanza rimane, allora vale la pena esaminare il catalogo di lingua di quella versione.

Precauzioni in produzione

Tre raccomandazioni valide per qualsiasi ambiente con utenti al lavoro:

  • Preferisca la cache specifica anziché svuotare tutto. Il sintomo indica quasi sempre una sola di esse.
  • Eviti le ore di punta quando svuota l'opcode, e in GLPI 12 anche per lo svuotamento generale, dato che i template vengono poi compilati al primo accesso a ciascuna schermata. La ricompilazione avviene su richiesta, quindi il costo ricade proprio su chi sta usando il sistema in quel momento.
  • Non lasci attiva la modalità debug. Oltre al sovraccarico, espone a schermo dettagli tecnici dell'ambiente.

Quando il problema non è la cache

Se ha svuotato la cache giusta e il comportamento persiste, due aspetti meritano una verifica prima di indagare oltre. Primo, se la modifica è realmente arrivata al server: per i plugin, confermi la versione installata, non quella pubblicata. Secondo, se la sua lingua dispone di un catalogo: se il plugin traduce verso es_ES e il suo profilo utilizza una variante regionale priva di catalogo proprio, GLPI ripiega sul testo originale.


Revisionato dal team NexTool Solutions.

Domande Frequenti

No. La cache è una copia temporanea di qualcosa che GLPI sa ricostruire. Impostazioni, ticket, asset e regole risiedono nel database e non vengono toccati. L'unico effetto collaterale è una lentezza momentanea durante la ricostruzione.

Non esiste una routine consigliata. La cache non è qualcosa da svuotare periodicamente per igiene; si invalida da sola nella maggior parte dei casi. La svuoti quando c'è un sintomo concreto, e soltanto la cache corrispondente.

Per le cache gestite da GLPI, no. Per la cache opcode di PHP, il pulsante dell'interfaccia se ne occupa nella maggior parte delle installazioni; negli ambienti in cui PHP gira in un processo separato, ricaricare il servizio PHP-FPM produce lo stesso effetto.

Se il testo vecchio è ricomparso, la cache è stata ricostruita a partire dalla stessa origine obsoleta. In tal caso il problema non è la cache, ma il file di traduzione sul server, e conviene verificare se la versione installata del plugin è davvero quella che porta la correzione.

Hai bisogno di aiuto?