How can I delete specific jobs from Resque queue without clearing the whole queue?
Asked Answered
W

4

31

I'm using Resque workers to process job in a queue, I have a large number of jobs > 1M in a queue and have some of the jobs that I need to remove ( added by error). Crating the queue with the jobs was not an easy tasks, so clearing the queue using resque-web and adding the correct jobs again is not an option for me.

Appreciate any advice. Thanks!

Wieldy answered 23/4, 2012 at 4:53 Comment(1)
Did you find a solution to this? Was it very slow to use destroy?Ebonieebonite
S
24

In resque's sources (Job class) there's such method, guess it's what you need :)

# 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)
Spannew answered 23/4, 2012 at 7:0 Comment(1)
If you're using ActiveJob, Resque::Job.destroy isn't going to be helpful, check out this answer: #35589552Marrilee
B
24

To remove a specific job from queue you can use the destroy method. It's very easy to use, For example if you want to remove a job with class Post and id x, which is in queue named queue1 You can do like this..

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

If you want to remove all the jobs of particular type from a queue you can use

Resque::Job.destroy(QueueName, ClassName) 

You can find it's documentation at

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

Bowhead answered 7/8, 2012 at 5:55 Comment(0)
S
6

The above solutions work great if you know all of the arguments passed to the job. If you have a situation where you know some of the arguments passed to the job the following script will work:

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
Smatter answered 1/9, 2017 at 15:35 Comment(0)
Z
0

Didn't seem to have luck running "Resque::Job.destroy(QueueName, ClassName)" and i am not using active job. This seemed to work for me.

(Resque::Failure.count-1).downto(0).each do |error_index_number|     
  failure = Resque::Failure.all(error_index_number)
  next unless failure['payload']['class'] == ClassName.name
  
  Resque::Failure.remove(error_index_number)
end
Zeitler answered 29/5 at 13:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.