Sidekiq не запускается после включения Zeitwerk в Docker dev

Недавно мы обновились с версии 2.4.0.beta4 до 2.4.0.beta5, и Sidekiq не запускается, выдавая следующий стек ошибок:

> $ bundle exec sidekiq -C config/sidekiq.yml
> uninitialized constant 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>'

Не могли бы вы подсказать, куда стоит посмотреть дальше? Спасибо!

Это не установка, выполненная по нашему официальному руководству, поэтому мы мало чем можем вам помочь.

Сейчас мы используем Discourse на OpenShift, так что это точно не стандартная установка. Я изучу официальное руководство и проверю, не упустил ли я что-то в текущем развёртывании. Спасибо.

На самом деле даже следующая команда Docker вызывает тот же самый стек трассировки в моей машине Vagrant с Discourse через VirtualBox:

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

Ты уверен в этом? В официальном руководстве ничего не сказано о ручном запуске Sidekiq, и там нет папки /home/discourse.

Ты разве запускаешь установку для разработки в продакшене :exploding_head:??

Я использую команды Docker для тестирования и разработки плагинов Discourse.

Другой скрипт, который я сейчас использую:

# Очистить временный кэш Discourse и запустить Rails в режиме разработки
vagrant ssh -c '(rm -rf ~/discourse/tmp/cache)'
vagrant ssh -c '(cd ~/discourse && sudo bin/docker/rails s)'

Конечно нет :smile:

@Falco, я думаю, это связано с

Что ты думаешь?

Возможно, так и есть. То, что вы не уточнили, что это ваша среда разработки, а не dev-окружение, не помогло.

Итак, вы утверждаете, что наша docker-среда разработки в данный момент сломана?

Да, похоже на это.

Откат этого коммита снова заставляет sidekiq работать.

Похоже, это для тебя, @kris.kotlarek

Хорошо, я понимаю, что произошло — это моя ошибка. Я удалил множество require_dependency, так как при использовании автозагрузчика Zeitwerk они больше не требуются.

Однако в application.rb у нас есть следующее:

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

Это означает, что Sidekiq не ищет директорию lib для поиска зависимостей, и мы явно указываем, что требуется в конкретных файлах.

Я могу вернуть require_dependency для файлов, используемых Sidekiq, или убрать эту проверку в application.rb.

Думаю, мы использовали явный require, чтобы сэкономить память для воркеров, поэтому, вероятно, стоит придерживаться этого подхода. Я верну require_dependency.

@sam, как ты думаешь?

Нужно убрать проверку. Мне она не нравится, потому что непонятно, станет ли ваш процесс Sidekiq или нет. В наших развёртываниях у нас так: unicorn master → fork → sidekiq worker. На момент fork файл application.rb уже был проанализирован.

@kris.kotlarek Спасибо за исправление. Sidekiq теперь работает вместе с официальными плагинами Discourse :+1:.

Однако большинство моих плагинов от сторонних разработчиков с задачами не работают сейчас :cry:. Скорее всего, это вызвано тем, что следующее изменение не было применено к их классам Jobs::. :arrow_down:


Сломанные плагины от сторонних разработчиков

Вы правы, теперь все Jobs::Onceoff, Jobs::Base и Jobs::Scheduled требуют использования ::

Я исправил discourse-whos-online и создал pull-запросы для других плагинов:

@kris.kotlarek Большое спасибо :partying_face: :+1:. Я ознакомился с вашим постом об автозагрузчике Zeitwerk. Планируется ли внедрение функции автоматической перезагрузки плагинов в режиме разработки для ускорения работы над плагинами?

Ещё остались места, содержащие require или require_dependency, но многие из них уже удалены.

Я думаю, что теперь код плагина должен автоматически перезагружаться без проблем. Нужно немного поэкспериментировать, чтобы убедиться, но у меня позитивные ощущения :slight_smile:

Похоже, нам сначала нужно включить это, согласно его документации. Я попробовал в режиме разработки, но изменения плагинов не были перезагружены :cry:

Это было бы здорово. У меня была надежда, но ваши слова дают мне еще больше надежды. Разработчики плагинов будут в восторге от этого.