class Google::Cloud::Env::Retries
outside of Google::Cloud::Env.
it to be available to other libraries. Currently it should not be used
We keep this private for now so we can move it in the future if we need
by an external mutex.
This class is not thread-safe by itself. Access should be protected
failure.
reached, or a configurable total time has elapsed since the first
until either a configured maximum number of attempts has been
A simple retry manager with optional delay and backoff. It retries
@private
#
def adjusted_delay start_time, cur_time
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
def advance_delay
def advance_delay @current_delay = (@delay_multiplier * @current_delay) + @delay_adder @current_delay = @max_delay if @max_delay && @current_delay > @max_delay end
def advance_retry cur_time
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
def finish!
-
(self)
-
def finish! @current_delay = nil self end
def finished?
-
(true, false)
-
def finished? @current_delay.nil? end
def initialize max_tries: 1,
-
delay_includes_time_elapsed
(true, false
) -- Whether to deduct any -
delay_adder
(Numeric
) -- Value added to the delay between -
delay_multiplier
(Numeric
) -- Multipler applied to the delay -
max_delay
(Numeric, nil
) -- Maximum delay between attempts, in -
initial_delay
(Numeric
) -- Initial delay between attempts, in -
max_time
(Numeric, nil
) -- The maximum amount of time in seconds -
max_tries
(Integer, nil
) -- Maximum number of attempts before we
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
def next start_time: nil
-
(Numeric, nil)
-
Parameters:
-
start_time
(Numeric, nil
) -- Optional start time in monotonic time
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
def reset!
-
(self)
-
def reset! @current_delay = :reset self end
def reset_dup
-
(Retries)
-
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
def setup_first_retry cur_time
def setup_first_retry cur_time @tries_remaining = @max_tries @deadline = @max_time ? cur_time + @max_time : nil @current_delay = @initial_delay end