我有一个安装了 sidekiq 和延迟作业 gem 的应用程序。当我在活动记录模型中触发handle_asynchronously 时,它似乎由sidekiq 处理,而我想触发delayed_job。
有没有办法为特定型号停用 sidekiq?
我有一个安装了 sidekiq 和延迟作业 gem 的应用程序。当我在活动记录模型中触发handle_asynchronously 时,它似乎由sidekiq 处理,而我想触发delayed_job。
有没有办法为特定型号停用 sidekiq?
更新:
Sidekiq 现在提供了delay
完全禁用其模块或将其别名为sidekiq_delay
. 请检查此以了解如何操作。https://github.com/mperham/sidekiq/wiki/Delayed-Extensions#disabling-extensions
对于旧版本的 sidekiq:
我使用这个猴子补丁来制作它,以便调用.sidekiq_delay()
转到 sidekiq 并.delay()
转到 DelayedJob。根据Viren的回答,我认为这也可以解决您的问题。
该补丁不那么复杂(只是一堆别名),并且使您能够有意识地决定delay
您实际调用的是哪个。
正如我在评论中提到的,为了让它工作,你必须重新定义/基本上猴子补丁这样的handle_asynchronously
方法
您喜欢的任何地方(但请确保已加载)
在您的config/initializers/patch.rb中,代码如下所示
module Patch
def handle_asynchronously(method, opts = {})
aliased_method, punctuation = method.to_s.sub(/([?!=])$/, ''), $1
with_method, without_method = "#{aliased_method}_with_delay#{punctuation}", "#{aliased_method}_without_delay#{punctuation}"
define_method(with_method) do |*args|
curr_opts = opts.clone
curr_opts.each_key do |key|
if (val = curr_opts[key]).is_a?(Proc)
curr_opts[key] = if val.arity == 1
val.call(self)
else
val.call
end
end
end
## Replace this with other syntax
# delay(curr_opts).__send__(without_method, *args)
__delay__(curr_opts).__send__(without_method, *args)
end
alias_method_chain method, :delay
end
end
Module.send(:include,Patch)
而且我相信其余的一切都会按照他们应该的方式进行:)
Delayed::Jobdelay
在 Object 上包含方法,Sidekiqdelay
在 ActiveRecord 上包含它方法因此,当类尝试调用delay
它时,查找它的祖先类(包括 Eigen 类)并找到定义或包含在 ActiveRecord::Base 类中的方法(其中是sidekiq延迟)
为什么会__delay__
起作用,因为别名定义了现有方法的副本,即delay
DelayedJob 的方法,因此当您调用该__delay__
方法时,它会调用delay
方法定义DelayedJob
包含到Object
虽然解决方案是位补丁,但它的工作原理。请记住,每个直接 .delay
的方法调用都是调用 SideKiq 的delay
方法,而不是调用 DelayedJob 的方法来调用delay
您总是以这种方式调用的 DelayedJob 方法__delay__
就我个人而言,Monkey Patching 只是一种不好的做法,我宁愿不为单个应用程序使用 2 个完全不同的后台处理库来完成相同的任务。如果任务是在后台处理事情,为什么不能使用单个库来完成,delayed_job
或者sidekiq
(为什么你需要它们两个)
因此,重点和简单的事情是让您的后台处理对未来更加轻松东西
希望这有帮助