L'activation de YJIT via Template ne fonctionne pas

Bonjour,

Je gère une installation Discourse auto-hébergée (2026.5.0-latest). Aujourd’hui, j’ai essayé d’activer YJIT. J’ai ajouté "templates/enable-ruby-yjit.yml" à containers/app.yml et reconstruit l’application.

Une fois la reconstruction terminée, quelque chose d’intéressant s’est produit. Dans le conteneur Docker, j’ai exécuté env | grep RUBY_YJIT_ENABLE et obtenu RUBY_YJIT_ENABLE=1. Jusque-là, tout va bien. Mais ensuite, j’ai exécuté sudo -u discourse RAILS_ENV=production bundle exec rails runner 'puts "YJIT activé : #{RubyVM::YJIT.enabled?}"; puts RUBY_DESCRIPTION'… j’ai obtenu :

YJIT activé : false

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

YJIT n’était donc pas activé, malgré l’ajout du modèle enable-ruby-yjit.yml. Ensuite, lorsque j’ai exécuté sudo -u discourse RAILS_ENV=production bundle exec rails runner 'puts "GlobalSetting.yjit_enabled=#{GlobalSetting.yjit_enabled}"', j’ai obtenu GlobalSetting.yjit_enabled= — une valeur nil !

Quoi qu’il en soit, après avoir un peu bidouillé, j’ai finalement réussi à activer YJIT en ajoutant ce qui suit à containers/app.yml :

env:
  DISCOURSE_YJIT_ENABLED: true

Je suis convaincu qu’il y a un bug quelque part (GlobalSetting.yjit_enabled ne devrait jamais retourner nil), mais la définition de la variable d’environnement a fonctionné, et j’espère que quelqu’un qui cherche cela sur Google trouvera ce sujet.

N’est-ce pas un mauvais diagnostic ? Vous vérifiez l’ENV d’un nouveau processus Ruby lancé au lieu de celui qui exécute le serveur web réel.

Si vous inspectez /proc/<pid>/environ du processus Pitchfork, vous verrez la variable d’environnement YJIT.

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

Le simple fait de vérifier la présence d’une variable d’environnement ne vous indique pas si Ruby s’exécute actuellement avec YJIT activé. Dans ce cas précis, la variable d’environnement est définie, mais quelque chose d’autre écrasait la variable utilisée par Rails pour activer (ou désactiver) YJIT au démarrage. Il n’existe aucune autre explication à ce que GlobalSetting.yjit_enabled= retourne nil, même sur une nouvelle instance de Rails. Il n’y a également aucune raison pour que YJIT soit désactivé sur une nouvelle instance de Rails.

Après avoir ajouté la variable d’environnement DISCOURSE_YJIT_ENABLED à mon fichier containers/app.yml :

  1. sudo -u discourse RAILS_ENV=production bundle exec rails runner 'puts "YJIT activé : #{RubyVM::YJIT.enabled?}"; puts RUBY_DESCRIPTION' retourne YJIT activé : true
  2. L’utilisation de la mémoire sur mon serveur augmente enfin légèrement.
  3. Je constate une véritable accélération sur mon forum.

Il devrait être facile de reproduire mes constatations. Ajoutez simplement le modèle et voyez par vous-même.

C’est incorrect. Au niveau de Ruby, la variable d’environnement est l’un des commutateurs officiels ; consultez la documentation officielle de Ruby à ce sujet ici :

C’est incorrect, car DISCOURSE_YJIT_ENABLED alimente uniquement GlobalSetting.yjit_enabledconfig.yjit dans config/application.rb. Rails l’utilise pour activer YJIT s’il n’est pas déjà activé. Il ne désactive pas un YJIT déjà activé. Ainsi, lorsque la variable d’environnement est définie, DISCOURSE_YJIT_ENABLED n’a aucun rôle à jouer.

Pour étayer mon propos, j’ai écrit un plugin qui indique si YJIT est activé sur mon processus web :

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

Vous êtes confus concernant le commutateur au niveau de Rails, ce qui est inutile puisque nous utilisons le commutateur au niveau de Ruby.

Hou ! Donc tu dis qu’on peut utiliser de façon fiable la variable d’environnement pour détecter si YJIT est activé ! Je ne le savais pas ; merci pour le lien vers la documentation Ruby.

Je suis un peu confus par quelque chose cependant. Comment est-il possible que env | grep RUBY_YJIT_ENABLE renvoie RUBY_YJIT_ENABLE=1, mais qu’une nouvelle instance de Rails dans le même conteneur, lorsqu’on lui demande d’afficher #{RubyVM::YJIT.enabled?}, renvoie false ? Cela ne devrait-il pas afficher true puisque, comme tu l’as mentionné, cette variable d’environnement fonctionne au niveau de Ruby ?

Tu es probablement très occupé et cela ne devrait pas avoir d’importance, donc pas besoin de répondre. Je devrais pouvoir le résoudre moi-même sur mon serveur. Pourrais-je avoir ton plugin, par hasard ? Je cherche un moyen d’être certain que mon serveur Discourse s’exécute sur une version de Ruby avec YJIT activé.

Je marquerai ta réponse comme solution après l’avoir reproduite.

Merci d’avance !

Je suis désolé, j’ai trouvé la solution.

sudo -u discourse nettoie l’environnement. L’utilisation du drapeau -E conserve l’environnement normal, et dans ce cas, sudo -E -u discourse RAILS_ENV=production bundle exec rails runner 'puts "YJIT enabled: #{RubyVM::YJIT.enabled?}"; puts RUBY_DESCRIPTION' renvoie :

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

Avec simplement le modèle ajouté.

Je m’excuse de vous avoir fait perdre du temps et j’ai marqué votre réponse comme la solution. Désolé pour cela. Merci d’avoir enquêté et pris le temps de répondre.