Module: Retriable

Defined in:
lib/retriable.rb,
lib/retriable/config.rb,
lib/retriable/version.rb,
lib/retriable/exponential_backoff.rb

Defined Under Namespace

Classes: Config, ExponentialBackoff

Constant Summary collapse

VERSION =
"3.2.1"

Class Method Summary collapse

Class Method Details

.configObject



15
16
17
# File 'lib/retriable.rb', line 15

def config
  @config ||= Config.new
end

.configure {|config| ... } ⇒ Object

Yields:



11
12
13
# File 'lib/retriable.rb', line 11

def configure
  yield(config)
end

.retriable(opts = {}) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/retriable.rb', line 27

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
    intervals = ExponentialBackoff.new(
      tries:          tries - 1,
      base_interval:  base_interval,
      multiplier:     multiplier,
      max_interval:   max_interval,
      rand_factor:    rand_factor
    ).intervals
  end

  tries = intervals.size + 1

  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) ⇒ Object



19
20
21
22
23
24
25
# File 'lib/retriable.rb', line 19

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