【问题标题】:conflict delayed_job / sidekiq冲突 delay_job / sidekiq
【发布时间】:2013-09-08 03:52:17
【问题描述】:

我有一个安装了 sidekiq 和延迟作业 gem 的应用程序。当我在活动记录模型中触发handle_asynchronously 时,它似乎由sidekiq 处理,而我想触发delayed_job。

有没有办法为特定模型停用 sidekiq?

【问题讨论】:

  • 请注意,delayed_job 是在非 activerecord 继承类上触发的
  • self 存储在其中 (db) 是什么,它是否会持续存在,因为如果记录持续存在,则不会延迟工作
  • 显然它可以正常工作,即使有关系,它也会保存对象和他的状态
  • 我的朋友你是 ruby​​ 元编程的受害者我相信检查thisthis 我认为唯一的办法是你可能使用__delay__ 方法而不是delay 因为那是什么handle_asynchronously 在内部调用 delay 方法,在您的情况下调用 SideKiq 因为感谢 ghost 类或 eigen 类:)
  • 我建议的一种方法是在您的lib 或您喜欢的任何地方覆盖this 一段代码:),并将此line 替换为类似__delay__(curr_opts).__send__(without_method, *args) 的内容,然后查看如果有效

标签: ruby-on-rails delayed-job sidekiq


【解决方案1】:

更新:

Sidekiq 现在提供了完全禁用其delay 模块或将其别名为sidekiq_delay 的方法。请检查此以了解如何操作。 https://github.com/mperham/sidekiq/wiki/Delayed-Extensions#disabling-extensions


对于旧版本的 sidekiq:

我使用this monkey patch 来实现,以便调用.sidekiq_delay() 转到sidekiq,而.delay() 转到DelayedJob。根据Viren的回答,我认为这也可以解决您的问题。

该补丁不那么复杂(只是一堆别名),并且让您能够有意识地决定您实际调用的是哪个delay

【讨论】:

    【解决方案2】:

    正如我在评论中提到的,为了让它正常工作,你必须重新定义/基本上猴子补丁 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_jobsidekiq (为什么你需要它们两个)

    因此,重点是让您的后台处理轻松应对未来,我真诚地建议您使用这两个库中的任何一个进行后台处理,我认为这将是 有效 的答案你的问题,而不是猴子修补做其他疯狂的事情

    希望有帮助

    【讨论】:

      猜你喜欢
      • 2017-01-20
      • 2013-09-19
      • 2016-04-18
      • 1970-01-01
      • 2017-03-22
      • 2011-11-22
      • 2016-02-25
      • 2011-08-04
      • 2021-06-17
      相关资源
      最近更新 更多