Module: OCI::Retry

Defined in:
lib/oci/retry/retry.rb,
lib/oci/retry/retry_config.rb,
lib/oci/retry/functions/sleep.rb,
lib/oci/retry/internal/retry_state.rb,
lib/oci/retry/functions/should_retry_on_error.rb

Overview

Module for retry strategies for use with the SDK when calling OCI services

Defined Under Namespace

Modules: Functions, Internal Classes: RetryConfig

Class Method Summary collapse

Class Method Details

.default_retry_configOCI::Retry::RetryConfig

Create a default retry configuration defined by OCI SDK



75
76
77
78
79
80
81
82
83
84
85
# File 'lib/oci/retry/retry.rb', line 75

def self.default_retry_config
  OCI::Retry::RetryConfig.new(
    base_sleep_time_millis: 1000,
    exponential_growth_factor: 2,
    should_retry_exception_proc: OCI::Retry::Functions::ShouldRetryOnError.default_retry_strategy_proc,
    sleep_calc_millis_proc: OCI::Retry::Functions::Sleep.exponential_backoff_with_full_jitter,
    max_attempts: 7,
    max_elapsed_time_millis: 300_000, # 5 minutes
    max_sleep_between_attempts_millis: 30_000
  )
end

.generate_opc_retry_token(token_length = 32) ⇒ String

Generates a token which can be used as a value for the opc-retry-token header value. The token will consist of uppercase letters (A-Z), lowercase letters (a-z) and digits (0-9)

Parameters:

  • token_length (Integer) (defaults to: 32)

    how many characters the token should be

Returns:

  • (String)


62
63
64
65
66
67
68
69
70
# File 'lib/oci/retry/retry.rb', line 62

def self.generate_opc_retry_token(token_length = 32)
  raise 'The token must be at least one character long' if token_length.nil? || token_length < 1

  available_chars = ('a'..'z').to_a + ('A'..'Z').to_a + ('0'..'9').to_a
  retry_token = ''
  token_length.times { retry_token << available_chars[rand(available_chars.size)] }

  retry_token
end

.make_retrying_call(retry_config, call_name: nil) ⇒ Object

Takes a block and then executes it with retries based on the provided configuration.

Parameters:

  • retry_config (OCI::Retry::RetryConfig)

    The configuration to be used for retries, defining what exceptions to retry on, how to calculate sleep times between retries etc. If the parameter value is nil then no retries are performed and the block is called once

  • operation_name (String)

    A friendly name for the operation being called so that it can be written to the logs

Returns:

  • (Object)

    The result of the block passed to this method



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/oci/retry/retry.rb', line 20

def self.make_retrying_call(retry_config, call_name: nil)
  raise 'A block must be provided' unless block_given?

  # If no retry configuration has been given, just do a single call
  return yield if retry_config.nil?

  retry_state = OCI::Retry::Internal::RetryState.new
  retry_state.start

  loop do
    begin
      OCI.logger.debug("[RETRYING_CALL] #{call_name}") if OCI.logger
      return yield
    rescue => e # rubocop:disable Style/RescueStandardError
      retry_state.increment_attempts
      retry_state.last_exception = e
      if retry_config.should_retry?(retry_state)
        if OCI.logger
          OCI.logger.debug(
            "[RETRYING] #{call_name} failed. Sleeping then retrying. Retry state: #{retry_state}"
          )
        end
        retry_config.do_sleep(retry_state)
      else
        if OCI.logger
          OCI.logger.debug(
            "[RETRIES_EXHAUSTED] #{call_name} failed and exhausted retries. Retry state: #{retry_state}"
          )
        end
        raise
      end
    end
  end
end