Habilitar YJIT via Template não funciona

Olá,

Eu administro uma instalação do Discourse auto-hospedada (2026.5.0-latest). Hoje, tentei ativar o YJIT. Adicionei "templates/enable-ruby-yjit.yml" ao containers/app.yml e reconstruí o aplicativo.

Após a conclusão da reconstrução, algo interessante aconteceu. Dentro do contêiner Docker, executei env | grep RUBY_YJIT_ENABLE e obtive RUBY_YJIT_ENABLE=1. Até aqui, tudo bem. Mas, em seguida, executei sudo -u discourse RAILS_ENV=production bundle exec rails runner 'puts "YJIT enabled: #{RubyVM::YJIT.enabled?}"; puts RUBY_DESCRIPTION'… e obtive:

YJIT enabled: false

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

Portanto, o YJIT não foi ativado, apesar de ter adicionado o modelo enable-ruby-yjit.yml. Então, quando executei sudo -u discourse RAILS_ENV=production bundle exec rails runner 'puts "GlobalSetting.yjit_enabled=#{GlobalSetting.yjit_enabled}"', obtive GlobalSetting.yjit_enabled= — um valor nil!

De qualquer forma, depois de mexer um pouco mais nisso, finalmente consegui ativar o YJIT adicionando o seguinte ao containers/app.yml:

env:
  DISCOURSE_YJIT_ENABLED: true

Tenho certeza de que há um bug em algum lugar (GlobalSetting.yjit_enabled não deveria nunca retornar nil), mas definir a variável de ambiente funcionou, e espero que alguém que esteja pesquisando no Google sobre isso encontre este tópico.

Isso não é um diagnóstico equivocado? Você está verificando o ENV de um novo processo Ruby recém-criado, em vez do que está executando o servidor web real.

Se você inspecionar /proc/<pid>/environ do processo mold do Pitchfork, verá a variável de ambiente YJIT lá.

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

Observar a presença de uma variável de ambiente não diz nada sobre se o Ruby está atualmente sendo executado com o YJIT ativado. Neste caso específico, a variável de ambiente está definida, mas algo mais estava sobrescrevendo a variável que o Rails usa para ativar (ou desativar) o YJIT na inicialização. Não há outra explicação para o fato de GlobalSetting.yjit_enabled= retornar nil, mesmo em uma nova instância do Rails. Também não há motivo para que o YJIT seja desativado em uma nova instância do Rails.

Após adicionar a variável de ambiente DISCOURSE_YJIT_ENABLED ao meu containers/app.yml,

  1. sudo -u discourse RAILS_ENV=production bundle exec rails runner 'puts "YJIT enabled: #{RubyVM::YJIT.enabled?}"; puts RUBY_DESCRIPTION' retorna YJIT enabled: true
  2. O uso de memória no meu servidor finalmente aumenta um pouco.
  3. Vejo uma aceleração real no meu fórum.

Deve ser fácil replicar minhas descobertas. Basta adicionar o modelo e verificar.

Isso está errado. No nível do Ruby, a variável de ambiente é um dos alternadores oficiais; consulte a documentação oficial do Ruby sobre isso aqui:

Isso está errado, pois DISCOURSE_YJIT_ENABLED apenas alimenta GlobalSetting.yjit_enabledconfig.yjit em config/application.rb. O Rails usa isso para habilitar o YJIT se ele ainda não estiver ativo. Ele não desabilita um YJIT já habilitado. Portanto, quando a variável de ambiente está definida, DISCOURSE_YJIT_ENABLED não tem nenhuma função.

Para provar ainda mais meu ponto, escrevi um plugin que retorna se o YJIT está habilitado no meu processo web:

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

Você está confuso sobre o alternador no nível do Rails, o que é desnecessário, já que usamos o alternador no nível do Ruby.

Uau! Então você está dizendo que podemos usar de forma confiável a variável de ambiente para detectar se o YJIT está ativado! Eu não sabia disso; obrigado pelo link para a documentação do Ruby.

Estou um pouco confuso sobre algo, porém. Como é possível que env | grep RUBY_YJIT_ENABLE retorne RUBY_YJIT_ENABLE=1, mas uma nova instância do Rails no mesmo container, quando solicitada a imprimir #{RubyVM::YJIT.enabled?}, retorne false? Não deveria retornar true, já que, como você mencionou, essa variável de ambiente funciona no nível do Ruby?

Você provavelmente está muito ocupado e isso não deve importar, então não há necessidade de responder. Deveria ser capaz de resolver isso no meu próprio servidor. Por acaso, você poderia me passar o seu plugin? Quero uma maneira de ter certeza de que meu servidor Discourse está rodando em uma versão do Ruby com o YJIT ativado.

Vou marcar sua resposta como solução depois de replicar.

Obrigado desde já!

Peço desculpas, já resolvi.

sudo -u discourse limpa o ambiente. Usar a flag -E mantém o ambiente normal, e nesse caso sudo -E -u discourse RAILS_ENV=production bundle exec rails runner 'puts "YJIT enabled: #{RubyVM::YJIT.enabled?}"; puts RUBY_DESCRIPTION' retorna

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

Apenas com o modelo adicionado.

Peço desculpas por ter desperdiçado seu tempo e marquei sua resposta como a solução. Desculpe pelo ocorrido. Obrigado por investigar e por ter se dado ao trabalho de responder.