Starting with Rails 7, retry failed jobs indefinitely


Active Job is a framework in Rails, for declaring jobs and making them run asynchronously on a variety of queuing backends. It has built-in adapters for multiple queuing backends like Sidekiq, Resque, Delayed jobs, and others.

A small example of a background job is as shown below:

class EmailVerificationCode < ActiveJob::Base

  def perform(verification_code)
    # send verification code to user email
  end
end

A background job can fail due to many reasons like incorrect business logic, database failures, network issues or the queue itself is not functional.

We can pass a retry option to the background job which will specify the number of times a background job needs to be re-tried in case of failures.

With Sidekiq, we can globally configure the max_retries option by adding the following to our sidekiq.yml

:max_retries: 1

We can override the globally configured max_retries option for a particular job as below:

class EmailVerificationCode < ActiveJob::Base
  sidekiq_options retry: 5 # Only five retries and then to the Dead Job Queue

  def perform(verification_code)
    # send verification code to user email
  end
end

Retry jobs indefinitely from Rails 7

With the latest changes in Rails 7, developers can specify to run a background job indefinitely by passing :unlimited option.

We pass the :unlimited value to the attempts parameter of the retry_on method which notifies that the job should always be re-enqueued in case of failures.

class EmailVerificationCode < ActiveJob::Base
  retry_on AlwaysRetryException, attempts: :unlimited

  def perform(verification_code)
    # send verification code to user email
  end
end

The default value for the attempts: key is 5, so the job will be retired five times and if failed will get enqueued to dead queue.

This functionality is useful in cases where developers are sure the job failure will be resolved eventually. The reasons for failure could be infrastructural issues like a resource getting locked for a long time, the database is down or network issue.

Note:

This feature should be used with caution. Only those failures should be retired indefinitely, where developers are sure the failure will be resolved.