正如我在评论中提到的,为了让它正常工作,你必须重新定义/基本上猴子补丁 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::Job 在 Object 上包含 delay 方法,Sidekiq 在 ActiveRecord 上包含 delay 方法
因此,当该类尝试调用 delay 时,它会查找它的祖先类(包括 Eigen 类)
它找到定义或包含在 ActiveRecord::Base 类中的方法(即 sidekiq 延迟)
为什么 __delay__ 起作用,因为别名定义了现有方法的副本,即 DelayedJob 的 delay 方法,因此当您调用 __delay__ 方法时,它会调用 delay 方法定义 DelayedJob
包括Object
注意:
虽然解决方案是位补丁,但它的工作原理。请记住,每个直接的 .delay 方法调用都是调用 SideKiq 的 delay 方法,而不是调用 DelayedJob 来调用 DelayedJob delay 方法,你总是这样调用它__delay__
建议:
就我个人而言,Monkey Patching 只是一种不好的做法,我宁愿不为单个应用程序使用 2 个完全不同的后台处理库来完成相同的任务。如果任务是在后台处理事情,为什么不能使用单个库来完成 delayed_job 或 sidekiq (为什么你需要它们两个)
因此,重点是让您的后台处理轻松应对未来,我真诚地建议您使用这两个库中的任何一个进行后台处理,我认为这将是 有效 的答案你的问题,而不是猴子修补做其他疯狂的事情
希望有帮助