Search code examples
ruby-on-railsrubydelayed-job

Using delayed job I want to modify reschedule_at based on error message


Using the error, failure and reschedule_at callbacks is there a way to make reschedule_at time depend on what type of error i receive?

I have set the reschedule_at method but if affects all jobs of this type. I don't know where to handle this behavior based on error type and in what handler.


Solution

  • After some testing it seems that you can do custom rescheduling based on the particular job error message with the following approach:

    1. Define an instance variable in the job to hold the custom retry delay. This variable will get serialized to the database (or any other DelayedJob backend) among all other variables, i.e. its state will be preserved between job runs.

    2. In the error hook, set the delay to any value based on the error that you'll get in the exception parameter (which is an Exception object).

    3. Use that custom delay in the reschedule_at method.

    The solution leverages the fact that the reschedule_at method is called after the error hook. See the following example:

    class MyJob
    
      attr_accessor :retry_delay
    
      def initialize
        self.retry_delay = 5 # default retry delay
      end
    
      def error(job, exception)
        # set up a different the delay time on a specific error
        if exception.is_a? NameError
          self.retry_delay = 10
        end
      end
    
      def reschedule_at(current_time, attempts)
        current_time + retry_delay.seconds
      end
    
    end