Class: PerfectRetry

Inherits:
Object
  • Object
show all
Defined in:
lib/perfect_retry.rb,
lib/perfect_retry/config.rb,
lib/perfect_retry/version.rb

Defined Under Namespace

Classes: Config, TooManyRetry

Constant Summary collapse

REGISTERED_CONFIG =
{ }
DEFAULTS =
{
  limit: 5,
  rescues: [StandardError],
  dont_rescues: [],
  logger: Logger.new(STDERR),
  log_level: :info, # CHANGE(1.0): to be `nil`
  sleep: lambda{|n| n ** 2}, # CHANGE(1.0): to be exponential backoff algorithm
  ensure: lambda{},
  raise_original_error: false, # false for TooManyRetry, true for original error
  prefer_original_backtrace: false, # CHANGE(1.0): to be `true`
}.freeze
VERSION =
"0.5.0".freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config_key = nil, &block) ⇒ PerfectRetry

Returns a new instance of PerfectRetry.



57
58
59
60
61
# File 'lib/perfect_retry.rb', line 57

def initialize(config_key = nil, &block)
  @config = REGISTERED_CONFIG[config_key] || default_config
  block.call(@config) if block_given?
  @config.set_log_level
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



55
56
57
# File 'lib/perfect_retry.rb', line 55

def config
  @config
end

Class Method Details

.deregister_allObject



39
40
41
# File 'lib/perfect_retry.rb', line 39

def self.deregister_all
  REGISTERED_CONFIG.clear
end

.disable!Object



43
44
45
# File 'lib/perfect_retry.rb', line 43

def self.disable!
  @disabled = true
end

.disabled?Boolean

Returns:

  • (Boolean)


51
52
53
# File 'lib/perfect_retry.rb', line 51

def self.disabled?
  @disabled.nil? ? false : @disabled
end

.enable!Object



47
48
49
# File 'lib/perfect_retry.rb', line 47

def self.enable!
  @disabled = false
end

.register(name, &block) ⇒ Object



25
26
27
28
29
# File 'lib/perfect_retry.rb', line 25

def self.register(name, &block)
  config = Config.create_from_hash(DEFAULTS)
  block.call(config)
  REGISTERED_CONFIG[name] = config
end

.registered_config(key) ⇒ Object



35
36
37
# File 'lib/perfect_retry.rb', line 35

def self.registered_config(key)
  REGISTERED_CONFIG[key]
end

.registered_config_allObject



31
32
33
# File 'lib/perfect_retry.rb', line 31

def self.registered_config_all
  REGISTERED_CONFIG
end

.with_retry(config_key = nil, &block) ⇒ Object



21
22
23
# File 'lib/perfect_retry.rb', line 21

def self.with_retry(config_key = nil, &block)
  new(config_key).with_retry(&block)
end

Instance Method Details

#default_configObject



63
64
65
# File 'lib/perfect_retry.rb', line 63

def default_config
  Config.create_from_hash(DEFAULTS)
end

#should_retry?(count) ⇒ Boolean

Returns:

  • (Boolean)


105
106
107
108
# File 'lib/perfect_retry.rb', line 105

def should_retry?(count)
  return true unless config.limit
  count < config.limit
end

#sleep_before_retry(count) ⇒ Object



101
102
103
# File 'lib/perfect_retry.rb', line 101

def sleep_before_retry(count)
  sleep config.sleep_sec(count)
end

#with_retry(&block) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/perfect_retry.rb', line 67

def with_retry(&block)
  return block.call(0) if PerfectRetry.disabled?

  count = 0
  begin
    retry_with_catch(count, &block)
  rescue *config.dont_rescues => e
    raise e
  rescue *config.rescues => e
    e.backtrace.each do |line|
      config.logger.debug line
    end

    if should_retry?(count)
      count += 1
      config.logger.warn "[#{count}/#{config.limit || "Infinitiy"}] Retrying after #{config.sleep_sec(count)} seconds. Ocurred: #{e}(#{e.class})"
      sleep_before_retry(count)
      retry
    end

    if config.raise_original_error
      raise e
    else
      error = TooManyRetry.new("too many retry (#{config.limit} times)")
      if config.prefer_original_backtrace
        error.set_backtrace(e.backtrace)
      end
      raise error
    end
  ensure
    config.ensure.call
  end
end