class Google::Cloud::Env::Retries
@private
A simple retry manager with optional delay and backoff. It retries until either a configured maximum number of attempts has been reached, or a configurable total time has elapsed since the first failure.
This class is not thread-safe by itself. Access should be protected by an external mutex.
We keep this private for now so we can move it in the future if we need it to be available to other libraries. Currently it should not be used outside of Google::Cloud::Env
.
Public Class Methods
Source
# File lib/google/cloud/env/lazy_value.rb, line 886 def initialize max_tries: 1, max_time: nil, initial_delay: 0, max_delay: nil, delay_multiplier: 1, delay_adder: 0, delay_includes_time_elapsed: false @max_tries = max_tries&.to_i raise ArgumentError, "max_tries must be positive" if @max_tries && !@max_tries.positive? @max_time = max_time raise ArgumentError, "max_time must be positive" if @max_time && !@max_time.positive? @initial_delay = initial_delay raise ArgumentError, "initial_delay must be nonnegative" if @initial_delay&.negative? @max_delay = max_delay raise ArgumentError, "max_delay must be nonnegative" if @max_delay&.negative? @delay_multiplier = delay_multiplier @delay_adder = delay_adder @delay_includes_time_elapsed = delay_includes_time_elapsed reset! end
Create and initialize a retry manager.
@param max_tries [Integer,nil] Maximum number of attempts before we
give up altogether, or nil for no maximum. Default is 1, indicating one attempt and no retries.
@param max_time [Numeric,nil] The maximum amount of time in seconds
until we give up altogether, or nil for no maximum. Default is nil.
@param initial_delay [Numeric] Initial delay between attempts, in
seconds. Default is 0.
@param max_delay [Numeric,nil] Maximum delay between attempts, in
seconds, or nil for no max. Default is nil.
@param delay_multiplier [Numeric] Multipler applied to the delay
between attempts. Default is 1 for no change.
@param delay_adder [Numeric] Value added to the delay between
attempts. Default is 0 for no change.
@param delay_includes_time_elapsed [true,false] Whether to deduct any
time already elapsed from the retry delay. Default is false.
Public Instance Methods
Source
# File lib/google/cloud/env/lazy_value.rb, line 946 def finish! @current_delay = nil self end
Cause the retry limit to be reached immediately.
@return [self]
Source
# File lib/google/cloud/env/lazy_value.rb, line 927 def finished? @current_delay.nil? end
Returns true if the retry limit has been reached.
@return [true,false]
Source
# File lib/google/cloud/env/lazy_value.rb, line 962 def next start_time: nil raise "no tries remaining" if finished? cur_time = Process.clock_gettime Process::CLOCK_MONOTONIC if @current_delay == :reset setup_first_retry cur_time else advance_delay end advance_retry cur_time adjusted_delay start_time, cur_time end
Advance to the next attempt.
Returns nil if the retry limit has been reached. Otherwise, returns the delay in seconds until the next retry (0 for no delay). Raises an error if the previous call already returned nil.
@param start_time [Numeric,nil] Optional start time in monotonic time
units. Used if delay_includes_time_elapsed is set.
@return [Numeric,nil]
Source
# File lib/google/cloud/env/lazy_value.rb, line 936 def reset! @current_delay = :reset self end
Reset to the initial attempt.
@return [self]
Source
# File lib/google/cloud/env/lazy_value.rb, line 912 def reset_dup Retries.new max_tries: @max_tries, max_time: @max_time, initial_delay: @initial_delay, max_delay: @max_delay, delay_multiplier: @delay_multiplier, delay_adder: @delay_adder, delay_includes_time_elapsed: @delay_includes_time_elapsed end
Create a duplicate in the reset state
@return [Retries]
Private Instance Methods
Source
# File lib/google/cloud/env/lazy_value.rb, line 992 def adjusted_delay start_time, cur_time delay = @current_delay if @delay_includes_time_elapsed && start_time && delay delay -= cur_time - start_time delay = 0 if delay.negative? end delay end
Source
# File lib/google/cloud/env/lazy_value.rb, line 982 def advance_delay @current_delay = (@delay_multiplier * @current_delay) + @delay_adder @current_delay = @max_delay if @max_delay && @current_delay > @max_delay end
Source
# File lib/google/cloud/env/lazy_value.rb, line 987 def advance_retry cur_time @tries_remaining -= 1 if @tries_remaining @current_delay = nil if @tries_remaining&.zero? || (@deadline && cur_time + @current_delay > @deadline) end
Source
# File lib/google/cloud/env/lazy_value.rb, line 976 def setup_first_retry cur_time @tries_remaining = @max_tries @deadline = @max_time ? cur_time + @max_time : nil @current_delay = @initial_delay end