如何从Resque队列中删除特定的作业而不清除整个队列?

31
我正在使用 Resque 工作进程来处理排队中的任务。我的队列中有大量超过 1M 的工作,而我需要删除其中一些(因为它们是出于错误添加的)。创建包含这些工作的队列不是一项容易的任务,所以使用 resque-web 清除队列并再次添加正确的工作不适用于我。
非常感谢任何建议。谢谢!

你找到解决方案了吗?使用 destroy 很慢吗? - Jeffrey Basurto
3个回答

24

要从队列中删除特定的作业,您可以使用 destroy 方法。它非常容易使用, 例如,如果您想从名为 queue1 的队列中删除一个类为 Post 且 ID 为 x 的作业, 您可以这样做。

Resque::Job.destroy(queue1, Post, 'x')

如果您想从队列中删除特定类型的所有作业,则可以使用以下方法:

Resque::Job.destroy(QueueName, ClassName) 

你可以在这里找到它的文档:

http://www.rubydoc.info/gems/resque/Resque%2FJob.destroy


24
在resque的源代码(Job类)中,有这样一个方法,我猜这就是你需要的 :)
# Removes a job from a queue. Expects a string queue name, a
# string class name, and, optionally, args.
#
# Returns the number of jobs destroyed.
#
# If no args are provided, it will remove all jobs of the class
# provided.
#
# That is, for these two jobs:
#
# { 'class' => 'UpdateGraph', 'args' => ['defunkt'] }
# { 'class' => 'UpdateGraph', 'args' => ['mojombo'] }
#
# The following call will remove both:
#
#   Resque::Job.destroy(queue, 'UpdateGraph')
#
# Whereas specifying args will only remove the 2nd job:
#
#   Resque::Job.destroy(queue, 'UpdateGraph', 'mojombo')
#
# This method can be potentially very slow and memory intensive,
# depending on the size of your queue, as it loads all jobs into
# a Ruby array before processing.
def self.destroy(queue, klass, *args)

如果您正在使用ActiveJob,Resque::Job.destroy将不会有帮助,请查看这个答案:https://dev59.com/lpTfa4cB1Zd3GeqPQGVl#40066148 - Jared

6

如果你知道作业中所有的参数,上述解决方案非常有效。但如果有些参数不确定,下面的脚本可以帮助你:

queue_name = 'a_queue'
jobs = Resque.data_store.peek_in_queue(queue_name, 0, 500_000);
deleted_count = 0

jobs.each do |job|
  decoded_job = Resque.decode(job)
  if decoded_job['class'] == 'CoolJob' && decoded_job['args'].include?('a_job_argument')
    Resque.data_store.remove_from_queue(queue_name, job)
    deleted_count += 1
    puts "Deleted!"
  end
end

puts deleted_count

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接