【问题标题】:How to query Sidekiq queues by Job class, queue name and arguments?如何按作业类、队列名称和参数查询 Sidekiq 队列?
【发布时间】:2021-10-18 14:36:09
【问题描述】:

在再次入队之前,我必须检查是否已将相同的作业添加到队列中。

目前我使用此代码,但效率非常低,因为它将所有对象加载到内存中。有没有办法像普通的活动记录一样查询?

理想情况下,我会喜欢

Sidekiq::Queue.where(job_class: "SyncJob", queue_name:"high", arguments: [1,2,3])

当前代码:

def list_queued_jobs(job_class, queue_name,  arguments)
  found_jobs = []
  queues = Sidekiq::Queue.all
  queues.each do |queue|
    queue.each do |job|
      job.args.each do |arg|
        if arg['job_class'].to_s == job_class.to_s && arg['queue_name'] == queue_name && ActiveJob::Arguments.deserialize(arg['arguments']) == arguments
          found_jobs << job
        end
      end
    end
  end
  return found_jobs
end

【问题讨论】:

    标签: ruby-on-rails sidekiq rails-activejob


    【解决方案1】:

    没有开箱即用的解决方案,但有一种更简单的方法可以确定作业是否已排队 (true/false):

    def in_queues?(job_class, queue_name,  arguments = [])
      Sidekiq::Queue.new(queue_name).any? do |job|
        job_class == job.klass && job.args == arguments
      end
    end
    

    请记住,sidekiq 参数以数组的形式呈现。例如,如果你这样称呼你的工作:

    SyncJob.perform_async([1, 2, 3])
    

    然后您检查它是否已按如下方式排队:

    in_queues?("SyncJob", "high", [[1, 2, 3]])
    

    【讨论】:

    • 谢谢!它非常快!我刚刚在块内进行了此更改以使其工作 job['wrapped'].to_s == job_class.to_s && ActiveJob::Arguments.deserialize(job.args[0]['arguments']) == arguments
    • @sparkle: 是的,我打错了,应该是 klass 而不是 class) 但 args 似乎工作正常,无需在我的本地机器上反序列化
    • klass 是 "ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper" 而 job['wrapped'] 是 "SyncJob"
    • 啊,我明白了,你正在将它与 activejob 包装器一起使用,而我一直在使用简单的 Sidekiq 设置对其进行测试)无论如何,我很高兴它成功了!
    【解决方案2】:

    检查现有作业称为“唯一作业”。 Sidekiq Enterprise 提供此功能,一些 3rd 方 gem 也提供此功能。

    实现和使用您描述的代码是一个非常坏主意。

    【讨论】:

    猜你喜欢
    • 2013-06-16
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    • 2014-06-02
    • 2018-06-29
    • 2018-09-27
    • 2014-12-03
    • 1970-01-01
    相关资源
    最近更新 更多