Abilitare YJIT tramite Template non funziona

Ciao,

Amministro un’installazione di Discourse in self-hosted (2026.5.0-latest). Oggi ho provato ad attivare YJIT. Ho aggiunto "templates/enable-ruby-yjit.yml" a containers/app.yml e ho ricostruito l’applicazione.

Dopo il completamento della ricostruzione, è successo qualcosa di interessante. All’interno del contenitore Docker, ho eseguito env | grep RUBY_YJIT_ENABLE e ho ottenuto RUBY_YJIT_ENABLE=1. Fin qui tutto bene. Ma poi ho eseguito sudo -u discourse RAILS_ENV=production bundle exec rails runner 'puts "YJIT enabled: #{RubyVM::YJIT.enabled?}"; puts RUBY_DESCRIPTION' … e ho ottenuto:

YJIT enabled: false

ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +PRISM [x86_64-linux] 

Quindi YJIT non era attivo, nonostante avessi aggiunto il template enable-ruby-yjit.yml. Poi, quando ho eseguito sudo -u discourse RAILS_ENV=production bundle exec rails runner 'puts "GlobalSetting.yjit_enabled=#{GlobalSetting.yjit_enabled}"', ho ottenuto GlobalSetting.yjit_enabled= — un valore nil!

Comunque, dopo averci smanettato un po’ di più, sono finalmente riuscito ad attivare YJIT aggiungendo quanto segue a containers/app.yml:

env:
  DISCOURSE_YJIT_ENABLED: true

Sono certo che ci sia un bug da qualche parte (GlobalSetting.yjit_enabled non dovrebbe mai restituire nil), ma impostare la variabile d’ambiente ha funzionato, e spero che qualcuno che cerca su Google per questo problema trovi questo argomento.

Non è forse una diagnosi errata? Stai controllando l’ENV di un nuovo processo Ruby appena avviato invece di quello che esegue effettivamente il server web.

Se ispezioni /proc/<pid>/environ del processo Pitchfork, vedrai la variabile d’ambiente YJIT lì.

root@raspberrypi5:/var/discourse# cat /proc/3331660/environ | tr '\0' '\n' | grep -i yjit
RUBY_YJIT_ENABLE=1

Osservare la presenza di una variabile d’ambiente non fornisce alcuna informazione su Ruby sia attualmente in esecuzione con YJIT abilitato. In questo caso specifico, la variabile d’ambiente è impostata, ma qualcos’altro stava sovrascrivendo la variabile che Rails utilizza per abilitare (o disabilitare) YJIT all’avvio. Non esiste altra spiegazione per cui GlobalSetting.yjit_enabled= restituisca nil, anche su una nuova istanza di Rails. Non c’è nemmeno motivo per cui YJIT dovrebbe essere disattivato su una nuova istanza di Rails.

Dopo aver aggiunto la variabile d’ambiente DISCOURSE_YJIT_ENABLED al mio file containers/app.yml:

  1. sudo -u discourse RAILS_ENV=production bundle exec rails runner 'puts "YJIT enabled: #{RubyVM::YJIT.enabled?}"; puts RUBY_DESCRIPTION' restituisce YJIT enabled: true
  2. L’utilizzo della memoria sul mio server è finalmente aumentato leggermente.
  3. Ho notato un reale aumento delle prestazioni sul mio forum.

Dovrebbe essere facile replicare i miei risultati. Basta aggiungere il template e verificare.

Questo è sbagliato. A livello di Ruby, la variabile d’ambiente è uno dei toggle ufficiali; consulta la documentazione ufficiale di Ruby a questo proposito qui:

Questo è sbagliato, poiché DISCOURSE_YJIT_ENABLED alimenta solo GlobalSetting.yjit_enabledconfig.yjit in config/application.rb. Rails lo utilizza per abilitare YJIT solo se non è già attivo. Non disabilita un YJIT già abilitato. Quindi, quando la variabile d’ambiente è impostata, DISCOURSE_YJIT_ENABLED non ha alcun ruolo.

Per dimostrare ulteriormente il mio punto, ho scritto un plugin che restituisce se YJIT è abilitato nel mio processo web:

https://discourse-on-a-pi5.falco.dev/ruby-info

Sei confuso riguardo al toggle a livello di Rails, che è inutile poiché si utilizza il toggle a livello di Ruby.

Eh! Quindi stai dicendo che possiamo usare in modo affidabile la variabile d’ambiente per rilevare se YJIT è abilitato! Non lo sapevo; grazie per il link alla documentazione di Ruby.

Sono un po’ confuso su una cosa, però. Come è possibile che env | grep RUBY_YJIT_ENABLE restituisca RUBY_YJIT_ENABLE=1, ma una nuova istanza di Rails nello stesso container, quando chiede di stampare #{RubyVM::YJIT.enabled?}, restituisca false? Non dovrebbe restituire true dato che, come hai menzionato, questa variabile d’ambiente funziona a livello Ruby?

Probabilmente sei molto impegnato e questo non dovrebbe essere importante, quindi non c’è bisogno di rispondere. Dovrei essere in grado di capirlo da solo sul mio server. Potresti, per caso, darmi il tuo plugin? Voglio un modo per essere certo che il mio server Discourse sia in esecuzione su una versione di Ruby con YJIT abilitato.

Contrassegnerò la tua risposta come soluzione dopo averla replicata.

Grazie in anticipo!

Mi scuso, ho risolto il problema.

sudo -u discourse pulisce l’ambiente. Usare il flag -E mantiene l’ambiente normale, e in quel caso sudo -E -u discourse RAILS_ENV=production bundle exec rails runner 'puts "YJIT enabled: #{RubyVM::YJIT.enabled?}"; puts RUBY_DESCRIPTION' restituisce

YJIT enabled: true
ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +YJIT +PRISM [x86_64-linux]

Con solo il modello aggiunto.

Mi scuso per aver perso il tuo tempo e ho contrassegnato la tua risposta come soluzione. Scusa per questo. Grazie per aver indagato e per il tempo dedicato a rispondere.