2

I've accidentally enqueued a bunch of jobs in Sidekiq. I do not want to wipe my entire Redis store (and reset ALL Sidekiq data and enqueued jobs to nil) but I would like to remove all enqueued jobs that can be identified by a given class. How would I do this?

Ivar
  • 5,102
  • 2
  • 31
  • 43
  • related to http://stackoverflow.com/questions/17224817/delete-redis-hash-values-in-bulk-based-on-the-hash-key-name – Ivar Apr 17 '14 at 16:43

3 Answers3

10

These answers were helpful, but didn't answer the original question for me. It's possible those solutions are out of date.

You have to access the job's args and grab it's actual job class within the loop scope. I tried the above and it did not work as expected because job.klass does not return what you'd expect it to.

This is what it returns in the terminal currently:

queue.each do |job|
  puts job.klass
end

ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper
=> nil

So my solution was to dig into the job's arguments like so:

queue = Sidekiq::Queue.new("job_queue_name")

queue.each do |job|
  puts job.args.first['job_class']
  job.delete if job.args.first['job_class'] == "Things::DoesThatThingJob"
end

I'm sure there's a way to write this more elegantly (maybe with a select?) But it's readable. Hope I was able to help others like me that were looking for something like this.

John Bachir
  • 22,495
  • 29
  • 154
  • 227
October Comstock
  • 541
  • 4
  • 15
  • 1
    This looks great and thanks for useful enhancements. I've made this the official answer. – Ivar Dec 06 '18 at 17:07
  • Glad I was able to help out @Ivar – October Comstock Dec 07 '18 at 00:13
  • I tried `jobs.args.first['job_class']` but it didn't work. @Ivar 's answer using `job.klass` works fine. Also, according to Sidekiq API doc, job.klass should be the right solution. – Wen Jul 28 '20 at 07:47
9

I found the Sidekiq API provides an easy way to do what I need:

queue = Sidekiq::Queue.new(queue_name)
queue.each do |job|
    puts job.klass
    job.delete if job.klass == job_class
end
Ivar
  • 5,102
  • 2
  • 31
  • 43
1

try a method like this in a helper module, where klass is the Worker class.

 def self.delete_jobs_for_worker(klass)

  jobs = Sidekiq::ScheduledSet.new
  jobs.select do |job|
    job.klass == 'Sidekiq::Extensions::DelayedClass' &&
        ((job_klass, job_method, args) = YAML.load(job.args[0])) &&
        job_klass == klass 
  end.map(&:delete)

end
blotto
  • 3,387
  • 1
  • 19
  • 19
  • 1
    Thanks for the tip! The code sample you provided led me to the doc pages I had missed, which had the information I needed to perform exactly what was required. – Ivar Apr 17 '14 at 22:14