Class: R4r::Retry
- Inherits:
-
Object
- Object
- R4r::Retry
- Defined in:
- lib/r4r/retry.rb
Overview
Decorator that wrap blocks and call it within retries.
Instance Attribute Summary collapse
-
#backoff ⇒ Array[Float]
The current value of backoff.
-
#budget ⇒ R4r::RetryBudget
The current value of budget.
Class Method Summary collapse
-
.backoff(backoff:, policy: nil, budget: nil) ⇒ R4r::Retry
Creates a Retry with backoff intervals.
-
.constant_backoff(num_retries:, backoff: 0.0, policy: nil, budget: nil) ⇒ R4r::Retry
Creates a Retry with fixed backoff rates.
Instance Method Summary collapse
-
#call(&block) ⇒ Object
Calls given block within retries.
-
#decorate(&block) ⇒ Proc
Decorates a given block within retries.
-
#initialize(backoff:, policy: nil, budget: nil) ⇒ Retry
constructor
Creates a new retries dectorator.
Constructor Details
#initialize(backoff:, policy: nil, budget: nil) ⇒ Retry
Creates a new retries dectorator.
42 43 44 45 46 47 48 49 |
# File 'lib/r4r/retry.rb', line 42 def initialize(backoff:, policy: nil, budget: nil) @policy = (policy || R4r::RetryPolicy.always) @backoff = Array.new(backoff).map { |i| i.to_f } @budget = budget != nil ? budget : R4r::RetryBudget.create raise ArgumentError, "backoff cannot be empty" if @backoff.empty? raise ArgumentError, "backoff values cannot be negative" unless @backoff.all? {|i| i.to_f >= 0.0 } end |
Instance Attribute Details
#backoff ⇒ Array[Float]
Returns the current value of backoff.
29 30 31 |
# File 'lib/r4r/retry.rb', line 29 def backoff @backoff end |
#budget ⇒ R4r::RetryBudget
Returns the current value of budget.
29 30 31 |
# File 'lib/r4r/retry.rb', line 29 def budget @budget end |
Class Method Details
.backoff(backoff:, policy: nil, budget: nil) ⇒ R4r::Retry
Creates a R4r::Retry with backoff intervals.
127 128 129 130 131 132 133 |
# File 'lib/r4r/retry.rb', line 127 def self.backoff(backoff:, policy: nil, budget: nil) raise ArgumentError, "backoff cannot be nil" if backoff.nil? raise ArgumentError, "backoff must be an array" unless backoff.is_a?(Array) raise ArgumentError, "backoff values cannot be negative" unless backoff.all? {|i| i.to_f >= 0.0 } R4r::Retry.new(backoff: backoff, policy: policy, budget: budget) end |
.constant_backoff(num_retries:, backoff: 0.0, policy: nil, budget: nil) ⇒ R4r::Retry
Creates a R4r::Retry with fixed backoff rates.
106 107 108 109 110 111 112 |
# File 'lib/r4r/retry.rb', line 106 def self.constant_backoff(num_retries:, backoff: 0.0, policy: nil, budget: nil) raise ArgumentError, "num_retries cannot be negative" unless num_retries.to_i >= 0 raise ArgumentError, "backoff cannot be negative" unless backoff.to_f >= 0.0 backoff = Array.new(num_retries.to_i) { backoff.to_f } R4r::Retry.new(backoff: backoff, policy: policy, budget: budget) end |
Instance Method Details
#call(&block) ⇒ Object
Calls given block within retries.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/r4r/retry.rb', line 61 def call(&block) return unless block_given? num_retry = 0 @budget.deposit while num_retry < @backoff.size begin return yield(num_retry) rescue => err raise err if err.is_a?(NonRetriableError) if (num_retry + 1 == @backoff.size) raise NonRetriableError.new(message: "Retry limit [#{@backoff.size}] reached: #{err}", cause: err) end unless @policy.call(error: err, num_retry: num_retry) raise NonRetriableError.new(message: "An error was rejected by policy: #{err}", cause: err) end unless @budget.try_withdraw raise NonRetriableError.new(message: "Budget was exhausted: #{err}", cause: err) end end sleep @backoff[num_retry] num_retry += 1 end end |
#decorate(&block) ⇒ Proc
Decorates a given block within retries.
54 55 56 |
# File 'lib/r4r/retry.rb', line 54 def decorate(&block) ->() { call { yield } } end |