module Resque::Plugins::ExponentialBackoff
If you want your job to retry on failure using a varying delay, simply extend your module/class with this module:
class DeliverSMS extend Resque::Plugins::ExponentialBackoff @queue = :mt_messages def self.perform(mt_id, mobile_number, message) heavy_lifting end end
Easily do something custom:
class DeliverSMS extend Resque::Plugins::ExponentialBackoff @queue = :mt_messages @retry_limit = 4 # retry delay in seconds; [0] => 1st retry, [1] => 2nd..4th retry. @backoff_strategy = [0, 60] # used to build redis key, for counting job attempts. def self.retry_identifier(mt_id, mobile_number, message) "#{mobile_number}:#{mt_id}" end self.perform(mt_id, mobile_number, message) heavy_lifting end end
Constants
- DEFAULT_RETRY_DELAY_MULTIPLICAND_MAX
- DEFAULT_RETRY_DELAY_MULTIPLICAND_MIN
Constants
@api public
Public Class Methods
Fail fast, when extended, if the “receiver” is misconfigured
@api private
# File lib/resque/plugins/exponential_backoff.rb, line 54 def self.extended(receiver) retry_delay_multiplicand_min = DEFAULT_RETRY_DELAY_MULTIPLICAND_MIN retry_delay_multiplicand_min = \ receiver.instance_variable_get(:@retry_delay_multiplicand_min) \ if receiver.instance_variable_defined?(:@retry_delay_multiplicand_min) retry_delay_multiplicand_max = DEFAULT_RETRY_DELAY_MULTIPLICAND_MAX retry_delay_multiplicand_max = \ receiver.instance_variable_get(:@retry_delay_multiplicand_max) \ if receiver.instance_variable_defined?(:@retry_delay_multiplicand_max) if retry_delay_multiplicand_min > retry_delay_multiplicand_max raise InvalidRetryDelayMultiplicandConfigurationException.new( %{"@retry_delay_multiplicand_min" must be less than or equal to "@retry_delay_multiplicand_max"} ) end end
Public Instance Methods
@abstract The backoff strategy is used to vary the delay between retry attempts
@return [Array] array of delays. index = retry attempt
@api public
# File lib/resque/plugins/exponential_backoff.rb, line 128 def backoff_strategy @backoff_strategy ||= [0, 60, 600, 3600, 10_800, 21_600] end
Selects the delay from the backoff strategy
@param _ [Exception] unused exception argument for signature parity @return [Number] seconds to delay until the next retry.
@api private
# File lib/resque/plugins/exponential_backoff.rb, line 87 def retry_delay(_ = nil) delay = backoff_strategy[retry_attempt] || backoff_strategy.last # if the values are the same don't bother generating a random number, if # the delta is zero, some platforms will raise an error if retry_delay_multiplicand_min == retry_delay_multiplicand_max delay_multiplicand = retry_delay_multiplicand_max else delay_multiplicand = \ rand(retry_delay_multiplicand_min..retry_delay_multiplicand_max) end (delay * delay_multiplicand).to_i end
@abstract The maximum value (upper-bound) for the range that is is used in calculating the retry-delay product
@return [Float]
@api public
# File lib/resque/plugins/exponential_backoff.rb, line 118 def retry_delay_multiplicand_max @retry_delay_multiplicand_max ||= DEFAULT_RETRY_DELAY_MULTIPLICAND_MAX end
@abstract The minimum value (lower-bound) for the range that is is used in calculating the retry-delay product
@return [Float]
@api public
# File lib/resque/plugins/exponential_backoff.rb, line 107 def retry_delay_multiplicand_min @retry_delay_multiplicand_min ||= DEFAULT_RETRY_DELAY_MULTIPLICAND_MIN end
Defaults to the number of delays in the backoff strategy
@return [Number] maximum number of retries
@api private
# File lib/resque/plugins/exponential_backoff.rb, line 77 def retry_limit @retry_limit ||= backoff_strategy.length end