Sidekiq falha ao iniciar após o Zeitwerk no docker dev

Recentemente atualizamos para a versão 2.4.0.beta5 a partir da 2.4.0.beta4, e o Sidekiq falha ao iniciar com o seguinte rastreamento de erro:

$ bundle exec sidekiq -C config/sidekiq.yml
Constante não inicializada: SiteSetting::SiteSettingExtension
/discourse/app/models/site_setting.rb:5:in `<class:SiteSetting>'
/discourse/app/models/site_setting.rb:3:in `<top (required)>'
/discourse/vendor/bundle/ruby/2.5.0/gems/zeitwerk-2.1.10/lib/zeitwerk/kernel.rb:23:in `require'
/discourse/vendor/bundle/ruby/2.5.0/gems/zeitwerk-2.1.10/lib/zeitwerk/kernel.rb:23:in `require'
/discourse/vendor/bundle/ruby/2.5.0/gems/activesupport-6.0.0/lib/active_support/dependencies/interlock.rb:14:in `block in loading'
/discourse/vendor/bundle/ruby/2.5.0/gems/activesupport-6.0.0/lib/active_support/concurrency/share_lock.rb:151:in `exclusive'
/discourse/vendor/bundle/ruby/2.5.0/gems/activesupport-6.0.0/lib/active_support/dependencies/interlock.rb:13:in `loading'
/discourse/config/initializers/004-message_bus.rb:120:in `<top (required)>'
/discourse/vendor/bundle/ruby/2.5.0/gems/railties-6.0.0/lib/rails/engine.rb:667:in `block in load_config_initializer'
/discourse/vendor/bundle/ruby/2.5.0/gems/activesupport-6.0.0/lib/active_support/notifications.rb:182:in `instrument'
/discourse/vendor/bundle/ruby/2.5.0/gems/railties-6.0.0/lib/rails/engine.rb:666:in `load_config_initializer'
/discourse/vendor/bundle/ruby/2.5.0/gems/railties-6.0.0/lib/rails/engine.rb:624:in `block (2 levels) in <class:Engine>'
/discourse/vendor/bundle/ruby/2.5.0/gems/railties-6.0.0/lib/rails/engine.rb:623:in `each'
/discourse/vendor/bundle/ruby/2.5.0/gems/railties-6.0.0/lib/rails/engine.rb:623:in `block in <class:Engine>'
/discourse/vendor/bundle/ruby/2.5.0/gems/railties-6.0.0/lib/rails/initializable.rb:32:in `instance_exec'
/discourse/vendor/bundle/ruby/2.5.0/gems/railties-6.0.0/lib/rails/initializable.rb:32:in `run'
/discourse/vendor/bundle/ruby/2.5.0/gems/railties-6.0.0/lib/rails/initializable.rb:61:in `block in run_initializers'
/usr/local/lib/ruby/2.5.0/tsort.rb:228:in `block in tsort_each'
/usr/local/lib/ruby/2.5.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'
/usr/local/lib/ruby/2.5.0/tsort.rb:422:in `block (2 levels) in each_strongly_connected_component_from'
/usr/local/lib/ruby/2.5.0/tsort.rb:431:in `each_strongly_connected_component_from'
/usr/local/lib/ruby/2.5.0/tsort.rb:421:in `block in each_strongly_connected_component_from'
/discourse/vendor/bundle/ruby/2.5.0/gems/railties-6.0.0/lib/rails/initializable.rb:50:in `each'
/discourse/vendor/bundle/ruby/2.5.0/gems/railties-6.0.0/lib/rails/initializable.rb:50:in `tsort_each_child'
/usr/local/lib/ruby/2.5.0/tsort.rb:415:in `call'
/usr/local/lib/ruby/2.5.0/tsort.rb:415:in `each_strongly_connected_component_from'
/usr/local/lib/ruby/2.5.0/tsort.rb:349:in `block in each_strongly_connected_component'
/usr/local/lib/ruby/2.5.0/tsort.rb:347:in `each'
/usr/local/lib/ruby/2.5.0/tsort.rb:347:in `call'
/usr/local/lib/ruby/2.5.0/tsort.rb:347:in `each_strongly_connected_component'
/usr/local/lib/ruby/2.5.0/tsort.rb:226:in `tsort_each'
/usr/local/lib/ruby/2.5.0/tsort.rb:205:in `tsort_each'
/discourse/vendor/bundle/ruby/2.5.0/gems/railties-6.0.0/lib/rails/initializable.rb:60:in `run_initializers'
/discourse/vendor/bundle/ruby/2.5.0/gems/railties-6.0.0/lib/rails/application.rb:363:in `initialize!'
/discourse/vendor/bundle/ruby/2.5.0/gems/railties-6.0.0/lib/rails/railtie.rb:190:in `public_send'
/discourse/vendor/bundle/ruby/2.5.0/gems/railties-6.0.0/lib/rails/railtie.rb:190:in `method_missing'
/discourse/config/environment.rb:7:in `<top (required)>'
/discourse/vendor/bundle/ruby/2.5.0/gems/sidekiq-5.2.7/lib/sidekiq/cli.rb:288:in `boot_system'
/discourse/vendor/bundle/ruby/2.5.0/gems/sidekiq-5.2.7/lib/sidekiq/cli.rb:46:in `run'
/discourse/vendor/bundle/ruby/2.5.0/gems/sidekiq-5.2.7/bin/sidekiq:12:in `<top (required)>'
/discourse/vendor/bundle/ruby/2.5.0/bin/sidekiq:23:in `load'
/discourse/vendor/bundle/ruby/2.5.0/bin/sidekiq:23:in `<top (required)>'
/usr/local/lib/ruby/site_ruby/2.5.0/bundler/cli/exec.rb:74:in `load'
/usr/local/lib/ruby/site_ruby/2.5.0/bundler/cli/exec.rb:74:in `kernel_load'
/usr/local/lib/ruby/site_ruby/2.5.0/bundler/cli/exec.rb:28:in `run'
/usr/local/lib/ruby/site_ruby/2.5.0/bundler/cli.rb:463:in `exec'
/usr/local/lib/ruby/site_ruby/2.5.0/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/usr/local/lib/ruby/site_ruby/2.5.0/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'
/usr/local/lib/ruby/site_ruby/2.5.0/bundler/vendor/thor/lib/thor.rb:387:in `dispatch'
/usr/local/lib/ruby/site_ruby/2.5.0/bundler/cli.rb:27:in `dispatch'
/usr/local/lib/ruby/site_ruby/2.5.0/bundler/vendor/thor/lib/thor/base.rb:466:in `start'
/usr/local/lib/ruby/site_ruby/2.5.0/bundler/cli.rb:18:in `start'
/usr/local/bin/bundle:30:in `block in <main>'
/usr/local/lib/ruby/site_ruby/2.5.0/bundler/friendly_errors.rb:124:in `with_friendly_errors'
/usr/local/bin/bundle:22:in `<main>'
```\n
Alguma orientação sobre onde procurar a seguir? Obrigado!

Esta não é uma instalação que seguiu nosso guia oficial, então não há muito o que possamos ajudar você.

Atualmente estamos rodando o Discourse no OpenShift, então certamente não é uma instalação padrão. Vou revisar o guia oficial e verificar se perdi algo na implantação atual. Obrigado.

Na verdade, até mesmo o seguinte comando docker está disparando o mesmo rastreamento de pilha na minha máquina vagrant do discourse via virtualbox:

vagrant ssh -c '(cd ~/discourse && sudo bin/docker/sidekiq)'

Tem certeza sobre isso? O guia oficial não menciona nada sobre inícios manuais do Sidekiq e não há uma pasta /home/discourse nele.

Você está rodando uma instalação de desenvolvimento em produção :exploding_head:??

Estou usando os comandos do Docker para testar e desenvolver plugins do Discourse.

O outro script que estou usando atualmente é:

# Limpar o cache temporário do Discourse e iniciar o Rails de desenvolvimento
vagrant ssh -c '(rm -rf ~/discourse/tmp/cache)'
vagrant ssh -c '(cd ~/discourse && sudo bin/docker/rails s)'

Claro que não :smile:

@Falco Acho que está relacionado a

O que você acha?

Pode ser sim. O fato de você não ter esclarecido que se trata do seu ambiente de desenvolvimento e não de um ambiente de dev não ajudou.

Então você está dizendo que nossa configuração de desenvolvimento com Docker está atualmente quebrada?

Sim, parece ser isso.

Reverter esse commit faz o Sidekiq funcionar novamente.

Parece que esta é uma para você @kris.kotlarek

Ok, eu sei o que aconteceu aqui, é culpa minha. Removi muitos require_dependency pois eles não são mais necessários ao usar o autoloader Zeitwerk.

No entanto, em application.rb, temos isso:

if !Sidekiq.server?
  config.autoload_paths += Dir["#{config.root}/lib"]
end

O que significa que o Sidekiq não está procurando no diretório lib para encontrar dependências e definimos explicitamente o que é necessário em arquivos específicos.

Posso trazer de volta o require_dependency para os arquivos usados pelo Sidekiq ou remover essa proteção em application.rb.

Acho que usamos esse require explícito para economizar memória nos workers, então provavelmente devemos seguir esse caminho. Vou trazer de volta o require_dependency.

@sam, qual é a sua opinião?

Devemos remover a verificação. Não gosto dela porque você não tem como saber se seu processo se tornará um Sidekiq ou não. Em nossas implantações, temos: unicorn master → fork → sidekiq worker. No momento do fork, o application.rb já havia sido analisado.

@kris.kotlarek Obrigado pela correção. O Sidekiq está funcionando agora junto com os plugins oficiais do Discourse :+1:.

A maioria dos meus plugins de terceiros com jobs não está funcionando agora :cry:. Provavelmente causado pelo seguinte commit não sendo aplicado em suas classes Jobs::. :arrow_down:


Plugins de terceiros quebrados

Você está certo, agora todos os Jobs::Onceoff, Jobs::Base e Jobs::Scheduled exigem ::

Corrigi o discourse-whos-online e criei pull requests para outros plugins:

@kris.kotlarek Muito obrigado :partying_face: :+1: . Eu li seu post sobre o auto-loader zeitwork. Existe um plano para habilitar um recurso de auto-recarregamento de plugins de desenvolvimento para acelerar o desenvolvimento de plugins?

Ainda existem locais que contêm require ou require_dependency, mas muitos foram removidos.

Acho que agora o código do plugin deve ser recarregado automaticamente sem problemas. Precisamos testar um pouco para ter certeza, mas estou otimista :slight_smile:

Parece que precisamos ativá-lo primeiro, conforme a documentação. Testei em desenvolvimento e nenhuma alteração no plugin foi recarregada :cry:

Isso seria ótimo. Eu tinha alguma esperança, mas suas palavras me dão ainda mais. Os desenvolvedores de plugins vão adorar isso.