module Retriable

Constants

VERSION

Public Instance Methods

config() click to toggle source
# File lib/retriable.rb, line 13
def config
  @config ||= Config.new
end
configure() { |config| ... } click to toggle source
# File lib/retriable.rb, line 9
def configure
  yield(config)
end
retriable(opts = {}) { |try| ... } click to toggle source
# File lib/retriable.rb, line 25
def retriable(opts = {})
  local_config = opts.empty? ? config : Config.new(config.to_h.merge(opts))

  tries             = local_config.tries
  base_interval     = local_config.base_interval
  max_interval      = local_config.max_interval
  rand_factor       = local_config.rand_factor
  multiplier        = local_config.multiplier
  max_elapsed_time  = local_config.max_elapsed_time
  intervals         = local_config.intervals
  timeout           = local_config.timeout
  on                = local_config.on
  on_retry          = local_config.on_retry
  sleep_disabled    = local_config.sleep_disabled

  exception_list = on.is_a?(Hash) ? on.keys : on
  start_time = Time.now
  elapsed_time = -> { Time.now - start_time }

  if intervals
    tries = intervals.size + 1
  else
    intervals = ExponentialBackoff.new(
      tries:          tries - 1,
      base_interval:  base_interval,
      multiplier:     multiplier,
      max_interval:   max_interval,
      rand_factor:    rand_factor
    ).intervals
  end

  tries.times do |index|
    try = index + 1

    begin
      return Timeout.timeout(timeout) { return yield(try) } if timeout
      return yield(try)
    rescue *[*exception_list] => exception
      if on.is_a?(Hash)
        raise unless exception_list.any? do |e|
          exception.is_a?(e) && ([*on[e]].empty? || [*on[e]].any? { |pattern| exception.message =~ pattern })
        end
      end

      interval = intervals[index]
      on_retry.call(exception, try, elapsed_time.call, interval) if on_retry
      raise if try >= tries || (elapsed_time.call + interval) > max_elapsed_time
      sleep interval if sleep_disabled != true
    end
  end
end
with_context(context_key, options = {}, &block) click to toggle source
# File lib/retriable.rb, line 17
def with_context(context_key, options = {}, &block)
  if !config.contexts.key?(context_key)
    raise ArgumentError, "#{context_key} not found in Retriable.config.contexts. Available contexts: #{config.contexts.keys}"
  end

  retriable(config.contexts[context_key].merge(options), &block) if block
end