Class: Gapic::Common::RetryPolicy

Inherits:
Object
  • Object
show all
Defined in:
lib/gapic/common/retry_policy.rb

Overview

Gapic Common retry policy base class.

A policy distinguishes "set to this value" from "never set". Every setting is stored as nil until someone supplies it, and the reader for each substitutes the corresponding DEFAULT_ constant on the way out, so a reader can never say which of the two happened. That distinction is what lets #apply_defaults fill in gaps without overwriting a caller's choices, and #overrides report what a caller actually asked for.

Constant Summary collapse

DEFAULT_INITIAL_DELAY =

Returns Default initial delay in seconds.

Returns:

  • (Numeric) —

    Default initial delay in seconds.

1
DEFAULT_MAX_DELAY =

Returns Default maximum delay in seconds.

Returns:

  • (Numeric) —

    Default maximum delay in seconds.

15
DEFAULT_MULTIPLIER =

Returns Default delay scaling factor for subsequent retry attempts.

Returns:

  • (Numeric) —

    Default delay scaling factor for subsequent retry attempts.

1.3
DEFAULT_RETRY_CODES =

Returns Default list of retry codes.

Returns:

  • (Array<String|Integer>) —

    Default list of retry codes.

[].freeze
DEFAULT_TIMEOUT =

Returns Default timeout threshold value in seconds.

Returns:

  • (Numeric) —

    Default timeout threshold value in seconds.

3600

Instance Method Summary collapse

Constructor Details

#initialize(initial_delay: nil, max_delay: nil, multiplier: nil, retry_codes: nil, timeout: nil, jitter: nil, retry_predicate: nil) ⇒ RetryPolicy

Create new Gapic::Common::RetryPolicy instance.

Parameters:

  • initial_delay (Numeric) (defaults to: nil) —

    Initial delay in seconds.

  • max_delay (Numeric) (defaults to: nil) —

    Maximum delay in seconds.

  • multiplier (Numeric) (defaults to: nil) —

    The delay scaling factor for each subsequent retry attempt.

  • retry_codes (Array<String|Integer>) (defaults to: nil) —

    List of retry codes.

  • timeout (Numeric) (defaults to: nil) —

    Timeout threshold value in seconds.

  • jitter (Numeric) (defaults to: nil) —

    Random jitter added to the delay in seconds.

  • retry_predicate (Proc, nil) (defaults to: nil) —

    The predicate to evaluate whether to retry on a given error. Optional. If the predicate is specified, it is run first. If it returns nil, the decision on whether to retry is made on the basis of retry_codes. Otherwise, the truthiness of the return value determines whether to retry.

Raises:

  • (ArgumentError)


59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/gapic/common/retry_policy.rb', line 59

def initialize initial_delay: nil, max_delay: nil, multiplier: nil, retry_codes: nil, timeout: nil,
               jitter: nil, retry_predicate: nil
  raise ArgumentError, "jitter cannot be negative" if jitter&.negative?
  if retry_predicate && !retry_predicate.respond_to?(:call)
    raise ArgumentError, "retry_predicate must respond to :call"
  end

  # Instance values are set as `nil` to determine whether values are overriden from default.
  @initial_delay = initial_delay
  @max_delay = max_delay
  @multiplier = multiplier
  @retry_codes = convert_codes retry_codes
  @timeout = timeout
  @jitter = jitter
  @retry_predicate = retry_predicate
  start!
end

Instance Method Details

#call(error = nil) ⇒ Boolean Also known as: perform_delay

Perform delay if and only if retriable.

If positional argument error is provided, the retriable logic uses retry_codes. Otherwise, timeout is used.

Returns:

  • (Boolean) —

    Whether the delay was executed.



172
173
174
175
176
# File 'lib/gapic/common/retry_policy.rb', line 172

def call error = nil
  should_retry = error.nil? ? retry_with_deadline? : retry_error?(error)
  return false unless should_retry
  perform_delay!
end

#delay ⇒ Numeric

Current delay value in seconds.

Returns:

  • (Numeric) —

    Time delay in seconds.



196
197
198
# File 'lib/gapic/common/retry_policy.rb', line 196

def delay
  @delay
end

#dup ⇒ RetryPolicy

Returns a duplicate in a non-executing state, i.e. with the deadline and current delay reset.

Returns:



154
155
156
157
158
159
160
161
162
# File 'lib/gapic/common/retry_policy.rb', line 154

def dup
  RetryPolicy.new initial_delay: @initial_delay,
                  max_delay: @max_delay,
                  multiplier: @multiplier,
                  retry_codes: @retry_codes,
                  timeout: @timeout,
                  jitter: @jitter,
                  retry_predicate: @retry_predicate
end

#initial_delay ⇒ Numeric

Returns Initial delay in seconds.

Returns:

  • (Numeric) —

    Initial delay in seconds.



78
79
80
# File 'lib/gapic/common/retry_policy.rb', line 78

def initial_delay
  @initial_delay || DEFAULT_INITIAL_DELAY
end

#jitter ⇒ Numeric

Returns Random jitter added to the delay in seconds.

Returns:

  • (Numeric) —

    Random jitter added to the delay in seconds.



103
104
105
# File 'lib/gapic/common/retry_policy.rb', line 103

def jitter
  @jitter || DEFAULT_JITTER
end

#max_delay ⇒ Numeric

Returns Maximum delay in seconds.

Returns:

  • (Numeric) —

    Maximum delay in seconds.



83
84
85
# File 'lib/gapic/common/retry_policy.rb', line 83

def max_delay
  @max_delay || DEFAULT_MAX_DELAY
end

#multiplier ⇒ Numeric

Returns The delay scaling factor for each subsequent retry attempt.

Returns:

  • (Numeric) —

    The delay scaling factor for each subsequent retry attempt.



88
89
90
# File 'lib/gapic/common/retry_policy.rb', line 88

def multiplier
  @multiplier || DEFAULT_MULTIPLIER
end

#perform_delay! ⇒ Boolean

Perform delay.

Returns:

  • (Boolean) —

    Whether the delay was executed.



184
185
186
187
188
189
# File 'lib/gapic/common/retry_policy.rb', line 184

def perform_delay!
  delay!
  increment_delay!
  @perform_delay_count += 1
  true
end

#perform_delay_count ⇒ Integer

Current number of times the delay has been performed

Returns:

  • (Integer)


205
206
207
# File 'lib/gapic/common/retry_policy.rb', line 205

def perform_delay_count
  @perform_delay_count
end

#retry_codes ⇒ Array<Integer>

Returns List of retry codes.

Returns:

  • (Array<Integer>) —

    List of retry codes.



93
94
95
# File 'lib/gapic/common/retry_policy.rb', line 93

def retry_codes
  @retry_codes || DEFAULT_RETRY_CODES
end

#retry_predicate ⇒ Proc?

The predicate to evaluate whether to retry on a given error. Optional.

When a predicate is specified:

  1. The predicate is executed first on the error.
  2. If it returns nil, the decision on whether to retry is made on the basis of retry_codes.
  3. Otherwise, the truthiness of the return value determines whether to retry.

Returns:

  • (Proc, nil)


116
117
118
# File 'lib/gapic/common/retry_policy.rb', line 116

def retry_predicate
  @retry_predicate
end

#start!(mock_delay: false) ⇒ Object

Start tracking the deadline and delay by initializing those values.

This is normally done when the object is constructed, but it can be done explicitly in order to reinitialize the state in case this retry policy was created in the past or is being reused.

Parameters:

  • mock_delay (boolean, Proc) (defaults to: false) —

    if truthy, delays are "mocked", meaning they do not actually take time, but are measured as if they did, which is useful for tests. If set to a Proc, it will be called whenever a delay would happen, and passed the delay in seconds, also useful for testing.



222
223
224
225
226
227
228
229
# File 'lib/gapic/common/retry_policy.rb', line 222

def start! mock_delay: false
  @mock_time = mock_delay ? Process.clock_gettime(Process::CLOCK_MONOTONIC) : nil
  @mock_delay_callback = mock_delay.respond_to?(:call) ? mock_delay : nil
  @deadline = cur_time + timeout
  @delay = initial_delay
  @perform_delay_count = 0
  self
end

#timeout ⇒ Numeric

Returns Timeout threshold value in seconds.

Returns:

  • (Numeric) —

    Timeout threshold value in seconds.



98
99
100
# File 'lib/gapic/common/retry_policy.rb', line 98

def timeout
  @timeout || DEFAULT_TIMEOUT
end