Задержка задания: как перезагрузить классы полезной нагрузки во время каждого вызова в режиме разработки

У меня работает отложенный работник. Когда я вызываю метод foo, рабочий печатает hello.

class User
  def foo
    puts "Hello"
  end
  handle_asynchronously :foo
end

Если я внесу некоторые изменения в метод foo, я должен перезапустить рабочего для отражения изменений. В режиме разработки это может стать довольно утомительным.

Я пытаюсь найти способ перезагрузить класс полезной нагрузки (в данном случае класс User) для каждого запроса. Я попробовал обезьяну заплатить библиотеку DelayedJob, чтобы вызвать require_dependency перед вызовом метода полезной нагрузки.

module Delayed::Backend::Base
  def payload_object_with_reload
    if Rails.env.development? and @payload_object_with_reload.nil?
      require_dependency(File.join(Rails.root, "app", "models", "user.rb"))
    end
    @payload_object_with_reload ||= payload_object_without_reload
  end
  alias_method_chain :payload_object, :reload
end

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

Кто-нибудь пробовал это раньше? Как бы вы посоветовали мне продолжить? Или у вас есть указатели на поиск кода перезагрузки класса Rails?

Ответы

Ответ 1

Мне удалось найти решение. Я использовал метод ActiveSupport::Dependencies.clear для очистки загруженных классов.

Добавьте файл с именем config/initializers/delayed_job.rb

Delayed::Worker.backend = :active_record
if Rails.env.development?
  module Delayed::Backend::Base
    def payload_object_with_reload
      if @payload_object_with_reload.nil?
        ActiveSupport::Dependencies.clear
      end
      @payload_object_with_reload ||= payload_object_without_reload
    end
    alias_method_chain :payload_object, :reload
  end
end

Ответ 2

Начиная с версии 4.0.6, DelayedJob перезагружается автоматически, если для параметра Rails.application.config.cache_classes установлено значение false:

В режиме разработки, если вы используете Rails 3.1+, ваш код приложения автоматически перезагружает каждые 100 заданий или когда очередь заканчивается. Вам больше не нужно перезапускать Delayed Job каждый раз, когда вы обновляете свой код в процессе разработки.