33

I have an application which uses Sidekiq. The web server process will sometimes put a job on Sidekiq, but I won't necessarily have the worker running. Is there a utility which I could call from the Rails console which would pull one job off the Redis queue and run the appropriate Sidekiq worker?

Jay Godse
  • 15,163
  • 16
  • 84
  • 131

2 Answers2

33

Here's a way that you'll likely need to modify to get the job you want (maybe like g8M suggests above), but it should do the trick:

> job = Sidekiq::Queue.new("your_queue").first
> job.klass.constantize.new.perform(*job.args)

If you want to delete the job:

> job.delete

Tested on sidekiq 5.2.3.

jhnatr
  • 503
  • 5
  • 9
4

I wouldn't try to hack sidekiq's API to run the jobs manually since it could leave some unwanted internal state but I believe the following code would work

# Fetch the Queue
queue = Sidekiq::Queue.new # default queue
# OR
# queue = Sidekiq::Queue.new(:my_queue_name)

# Fetch the job
# job = queue.first
# OR
job = queue.find do |job|
  meta = job.args.first
  # => {"job_class" => "MyJob", "job_id"=>"1afe424a-f878-44f2-af1e-e299faee7e7f", "queue_name"=>"my_queue_name", "arguments"=>["Arg1", "Arg2", ...]}

  meta['job_class'] == 'MyJob' && meta['arguments'].first == 'Arg1'
end

# Removes from queue so it doesn't get processed twice
job.delete

meta = job.args.first
klass = meta['job_class'].constantize
# => MyJob

# Performs the job without using Sidekiq's API, does not count as performed job and so on.
klass.new.perform(*meta['arguments'])

# OR

# Perform the job using Sidekiq's API so it counts as performed job and so on.
# klass.new(*meta['arguments']).perform_now

Please let me know if this doesn't work or if someone knows a better way to do this.

g8M
  • 1,253
  • 2
  • 9
  • 8