123456789_123456789_123456789_123456789_123456789_

Module: ActiveJob::Exceptions

Relationships & Source Files
Namespace Children
Modules:
Extension / Inclusion / Inheritance Descendants
Included In:
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
Defined in: activejob/lib/active_job/exceptions.rb

Overview

Provides behavior for retrying and discarding jobs on exceptions.

Constant Summary

Class Method Summary

::ActiveSupport::Concern - Extended

class_methods

Define class methods from given block.

included

Evaluate given block in context of base class, so that you can write class macros here.

prepended

Evaluate given block in context of base class, so that you can write class macros here.

append_features, prepend_features

Instance Method Summary

DSL Calls

included

[ GitHub ]


10
11
12
13
# File 'activejob/lib/active_job/exceptions.rb', line 10

included do
  class_attribute :retry_jitter, instance_accessor: false, instance_predicate: false, default: 0.0
  class_attribute :after_discard_procs, default: []
end

Instance Method Details

#determine_delay(seconds_or_duration_or_algorithm:, executions:, jitter: JITTER_DEFAULT) (private)

[ GitHub ]

  
# File 'activejob/lib/active_job/exceptions.rb', line 167

def determine_delay(seconds_or_duration_or_algorithm:, executions:, jitter: JITTER_DEFAULT)
  jitter = jitter == JITTER_DEFAULT ? self.class.retry_jitter : (jitter || 0.0)

  case seconds_or_duration_or_algorithm
  when :exponentially_longer, :polynomially_longer
    # This delay uses a polynomial backoff strategy, which was previously misnamed as exponential
    delay = executions**4
    delay_jitter = determine_jitter_for_delay(delay, jitter)
    delay + delay_jitter + 2
  when ActiveSupport::Duration, Integer
    delay = seconds_or_duration_or_algorithm.to_i
    delay_jitter = determine_jitter_for_delay(delay, jitter)
    delay + delay_jitter
  when Proc
    algorithm = seconds_or_duration_or_algorithm
    algorithm.call(executions)
  else
    raise "Couldn't determine a delay based on #{seconds_or_duration_or_algorithm.inspect}"
  end
end

#determine_jitter_for_delay(delay, jitter) (private)

[ GitHub ]

  
# File 'activejob/lib/active_job/exceptions.rb', line 188

def determine_jitter_for_delay(delay, jitter)
  return 0.0 if jitter.zero?
  Kernel.rand * delay * jitter
end

#executions_for(exceptions) (private)

[ GitHub ]

  
# File 'activejob/lib/active_job/exceptions.rb', line 193

def executions_for(exceptions)
  if exception_executions
    exception_executions[exceptions.to_s] = (exception_executions[exceptions.to_s] || 0) + 1
  else
    # Guard against jobs that were persisted before we started having individual executions counters per retry_on
    executions
  end
end

#retry_job(options = {})

Reschedules the job to be re-executed. This is useful in combination with rescue_from. When you rescue an exception from your job you can ask Active Job to retry performing your job.

Options

  • :wait - Enqueues the job with the specified delay in seconds

  • :wait_until - Enqueues the job at the time specified

  • :queue - Enqueues the job on the specified queue

  • :priority - Enqueues the job with the specified priority

Examples

class SiteScraperJob < ActiveJob::Base
  rescue_from(ErrorLoadingSite) do
    retry_job queue: :low_priority
  end

  def perform(*args)
    # raise ErrorLoadingSite if cannot scrape
  end
end
[ GitHub ]

  
# File 'activejob/lib/active_job/exceptions.rb', line 157

def retry_job(options = {})
  instrument :enqueue_retry, options.slice(:error, :wait) do
    enqueue options
  end
end

#run_after_discard_procs(exception) (private)

[ GitHub ]

  
# File 'activejob/lib/active_job/exceptions.rb', line 202

def run_after_discard_procs(exception)
  exceptions = []
  after_discard_procs.each do |blk|
    instance_exec(self, exception, &blk)
  rescue StandardError => e
    exceptions << e
  end
  raise exceptions.last unless exceptions.empty?
end