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!

Returns:
  • (self) -
def finish!
  @current_delay = nil
  self
end

def finished?

Returns:
  • (true, false) -
def finished?
  @current_delay.nil?
end

def initialize max_tries: 1,

Parameters:
  • 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

Returns:
  • (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!

Returns:
  • (self) -
def reset!
  @current_delay = :reset
  self
end

def reset_dup

Returns:
  • (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