Repository: rails/rails
File: activejob/lib/active_job/exceptions.rb (Ruby)

Code before:
      private_constant :JITTER_DEFAULT

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

        case seconds_or_duration_or_algorithm
        when  :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
          call_retry_delay_algorithm(algorithm, executions, error)
        else
          raise "Couldn't determine a delay based on #{seconds_or_duration_or_algorithm.inspect}"
        end
      end

      def call_retry_delay_algorithm(algorithm, executions, error)
        case algorithm.arity
        when 0, 1 then algorithm.call(executions)
        else algorithm.call(executions, error)
        end
      end

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

      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

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

Review comment (bug):
If arity is `0` this would fail no?

Also not sure it's really worth extracting that method.

Code after:
      private_constant :JITTER_DEFAULT

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

        case seconds_or_duration_or_algorithm
        when  :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.arity == 1 ? algorithm.call(executions) : algorithm.call(executions, error)
        else
          raise "Couldn't determine a delay based on #{seconds_or_duration_or_algorithm.inspect}"
        end
      end

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

      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

      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
  end
end