Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sidekiq retry count in job

Tags:

ruby

jobs

sidekiq

Is there a way to get the retry count for the current job?

I want the job to stop, not crash, after x retries. I would like to ask the retry count in the perform method so I could simply return if the retry count equals x.

def perform(args)
  return if retry_count > 5
  ...
end

Using Sidekiq 2.12.

Edit

I (not the OP) have the same question but for a different reason. If the job is being retried I want to do additional sanity checking to make sure the job is needed and to quit retrying if it is no longer expected to succeed because something external changed since it was queued.

So, is there a way to get the retry count for the current job? The current answers only suggest ways you can get around needing it or can get it from outside the job.

like image 905
Cimm Avatar asked Apr 14 '14 16:04

Cimm


People also ask

How do you retry a Sidekiq job?

Sidekiq will retry failures with an exponential backoff using the formula (retry_count ** 4) + 15 + (rand(30) * (retry_count + 1)) (i.e. 15, 16, 31, 96, 271, ... seconds + a random amount of time). It will perform 25 retries over approximately 21 days.

How do I manually run a Sidekiq job?

To run sidekiq, you will need to open a terminal, navigate to your application's directory, and start the sidekiq process, exactly as you would start a web server for the application itself. When the command executes you will see a message that sidekiq has started.

How does Sidekiq queue work?

Sidekiq server process pulls jobs from the queue in Redis and processes them. Like your web processes, Sidekiq boots Rails so your jobs and workers have the full Rails API, including Active Record, available for use. The server will instantiate the worker and call perform with the given arguments.


2 Answers

This can be accomplished by adding a sidekiq middleware to set the msg['retry_count'] as an instance variable of the job class.

Add a middleware (in Rails, it's usually a file in /config/initializers/ folder) like so:

class SidekiqMiddleware
    def call(worker, job, queue)
        worker.retry_count = job['retry_count'] if worker.respond_to?(:retry_count=)
        yield
    end
end

Sidekiq.configure_server do |config|
    config.server_middleware do |chain|
        chain.add SidekiqMiddleware
    end
end

In your job:

include Sidekiq::Worker
attr_accessor :retry_count

def retry_count
  @retry_count || 0
end

def perform(args)
  return if retry_count > 5
  ...
end
like image 163
Derek Avatar answered Sep 22 '22 16:09

Derek


you dont need to deal with this logic directly to accomplish what you want. simply add some configs to your worker as such..note the sidekiq_options . based on your comment below " prevent Sidekiq from moving the job to the dead jobs queue"

 class MyWorker  
     include Sidekiq::Worker
     sidekiq_options :retry => 5, :dead => false

      def perform
          #do some stuff
      end
 end

then the job should just retry 5 times and fail gracefully. also if you want to execute a code block once 5 retries are spent, the worker has a method called sidekiq_retries_exhausted where you could do some custom logging, etc.

like image 23
blotto Avatar answered Sep 20 '22 16:09

blotto