延迟作业:如何在开发模式下的每次调用期间重新加载有效负载类

Posted

技术标签:

【中文标题】延迟作业:如何在开发模式下的每次调用期间重新加载有效负载类【英文标题】:Delayed job: How to reload the payload classes during every call in Development mode 【发布时间】:2011-06-21 15:53:40 【问题描述】:

我正在运行一个延迟工作的工作人员。当我调用foo 方法时,worker 打印hello

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

如果我对 foo 方法进行一些更改,我必须重新启动工作程序以反映更改。在开发模式下,这可能会变得非常烦人。

我正在尝试找到一种方法来为每个请求重新加载有效负载类(在本例中为用户类)。我尝试猴子修补 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】:

从 4.0.6 版开始,如果 Rails.application.config.cache_classes 设置为 false,DelayedJob 会自动重新加载:

在开发模式下,如果您使用的是 Rails 3.1+,您的应用程序代码将每 100 个作业或队列完成时自动重新加载。您不再需要在每次更新开发中的代码时重新启动延迟作业。

【讨论】:

【参考方案2】:

这看起来可以在没有 alias_method 黑客的情况下解决您的问题:

https://github.com/Viximo/delayed_job-rails_reloader

【讨论】:

【参考方案3】:

我设法找到了解决方案。我使用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

【讨论】:

谢谢!这很好用,即使使用 mongoid 作为后端。我只需要删除第一行就可以了:) 不错!做了类似的事情,但作为separate script 并与foreman 一起使用 我不太明白为什么,但这会导致我的 Rails 内存在所有环境(包括生产环境)和非 DJ 实例中爆炸。

以上是关于延迟作业:如何在开发模式下的每次调用期间重新加载有效负载类的主要内容,如果未能解决你的问题,请参考以下文章

多线程下单例模式:懒加载(延迟加载)和即时加载

RPC 调用期间 GWT 冻结

如何让 NGINX 从 cron 作业重新启动/重新加载?

多线程下的立即加载与延迟加载

多线程下的立即加载与延迟加载

如何加载新版本react addon