Class: CMDx::Retry
- Inherits:
-
Object
- Object
- CMDx::Retry
- Defined in:
- lib/cmdx/retry.rb
Overview
Configurable retry-on-exception wrapper around a task’s ‘work`. Supports exception list, attempt `:limit`, base `:delay`, `:max_delay` cap, and `:jitter` strategy (symbol, proc, or a configured block). Declared via `Task.retry_on` and accumulates across inheritance.
Instance Attribute Summary collapse
-
#exceptions ⇒ Object
readonly
Returns the value of attribute exceptions.
Instance Method Summary collapse
-
#build(new_exceptions, new_options, &block) {|attempt, delay| ... } ⇒ Retry
Returns a new Retry layering ‘new_exceptions` and `new_options` onto the current one.
-
#delay ⇒ Float
Base delay in seconds.
-
#initialize(exceptions, options = EMPTY_HASH, &block) {|attempt, delay| ... } ⇒ Retry
constructor
A new instance of Retry.
-
#jitter ⇒ Symbol, ...
Jitter strategy or the block given to #initialize.
- #limit ⇒ Integer
-
#max_delay ⇒ Float?
Upper bound for computed delays.
-
#process(task = nil) {|attempt| ... } ⇒ Object
Executes the block up to ‘limit + 1` times.
-
#wait(attempt, task = nil, prev_delay = nil) ⇒ Float?
Sleeps ‘attempt`’s jittered/bounded delay.
Constructor Details
#initialize(exceptions, options = EMPTY_HASH, &block) {|attempt, delay| ... } ⇒ Retry
Returns a new instance of Retry.
23 24 25 26 27 |
# File 'lib/cmdx/retry.rb', line 23 def initialize(exceptions, = EMPTY_HASH, &block) @exceptions = exceptions.flatten @options = .freeze @block = block end |
Instance Attribute Details
#exceptions ⇒ Object (readonly)
Returns the value of attribute exceptions.
10 11 12 |
# File 'lib/cmdx/retry.rb', line 10 def exceptions @exceptions end |
Instance Method Details
#build(new_exceptions, new_options, &block) {|attempt, delay| ... } ⇒ Retry
Returns a new Retry layering ‘new_exceptions` and `new_options` onto the current one. Used for inheritance so subclasses extend rather than replace.
38 39 40 41 42 43 44 45 |
# File 'lib/cmdx/retry.rb', line 38 def build(new_exceptions, , &block) return self if new_exceptions.empty? merged_exceptions = exceptions | new_exceptions.flatten = @options.merge() self.class.new(merged_exceptions, , &block || @block) end |
#delay ⇒ Float
Returns base delay in seconds.
53 54 55 |
# File 'lib/cmdx/retry.rb', line 53 def delay @options[:delay] || 0.5 end |
#jitter ⇒ Symbol, ...
Returns jitter strategy or the block given to #initialize.
63 64 65 |
# File 'lib/cmdx/retry.rb', line 63 def jitter @options[:jitter] || @block end |
#limit ⇒ Integer
48 49 50 |
# File 'lib/cmdx/retry.rb', line 48 def limit @options[:limit] || 3 end |
#max_delay ⇒ Float?
Returns upper bound for computed delays.
58 59 60 |
# File 'lib/cmdx/retry.rb', line 58 def max_delay @options[:max_delay] end |
#process(task = nil) {|attempt| ... } ⇒ Object
Executes the block up to ‘limit + 1` times. Re-raises the last exception when attempts are exhausted.
113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/cmdx/retry.rb', line 113 def process(task = nil, &) return yield(0) if exceptions.empty? || !limit.positive? prev_delay = nil (limit + 1).times do |attempt| return yield(attempt) rescue *exceptions => e raise(e) if attempt >= limit raise(e) unless Util.satisfied?(@options[:if], @options[:unless], task, e, attempt) prev_delay = wait(attempt, task, prev_delay) end end |
#wait(attempt, task = nil, prev_delay = nil) ⇒ Float?
Sleeps ‘attempt`’s jittered/bounded delay. No-op when the base delay is zero.
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 100 101 102 103 |
# File 'lib/cmdx/retry.rb', line 75 def wait(attempt, task = nil, prev_delay = nil) return unless delay.positive? d = case jitter when NilClass delay when Symbol registry = retriers_registry(task) if registry.key?(jitter) registry.lookup(jitter).call(attempt, delay, prev_delay) else task.send(jitter, attempt, delay) end when Proc task.instance_exec(attempt, delay, &jitter) else if jitter.respond_to?(:call) jitter.call(attempt, delay) else delay end end d = d.clamp(0, max_delay) if max_delay Kernel.sleep(d) if d.positive? d end |