class Awspec::Helper::ClientWrap

Attributes

backoff[R]
backoff_limit[R]
client[R]
iteration[R]
symbol1[R]
symbol2[R]

Public Class Methods

new(real_client = nil) click to toggle source
# File lib/awspec/helper/client_wrap.rb, line 9
def initialize(real_client = nil)
  raise ArgumentError, 'Client can not be nil' if real_client.nil?

  config = Awspec::Config.instance
  @client        = real_client
  @backoff       = config[:client_backoff]
  @orig_backoff  = @backoff
  @iteration     = config[:client_iteration]
  @orig_iter     = @iteration
  @backoff_limit = config[:client_backoff_limit]
  # build the symbol we'll use to compare to any errors caught in method_missing
  # below.
  @symbol1 = real_client.class.to_s.split('::').shift(2).push('Errors', 'RequestLimitExceeded').join('::').to_sym
  @symbol2 = real_client.class.to_s.split('::').shift(2).push('Errors', 'Throttling').join('::').to_sym
end

Protected Instance Methods

method_missing(m, *args, &block) click to toggle source

used to capture only the “RequestLimitExceeded” error from an aws client api call. In the case of matching it we want to try again, backing off successively each time, until the backoff_limit is reached or exceeded, in which case, the error will be re-raised and it should fail as expected.

# File lib/awspec/helper/client_wrap.rb, line 32
def method_missing(m, *args, &block)
  begin
    results = client.send(m, *args, &block)
  rescue Exception => e # rubocop:disable Lint/RescueException
    raise unless (e.class.to_s == symbol1.to_s || e.class.to_s == symbol2.to_s) && backoff < backoff_limit

    @backoff = backoff + (iteration * iteration * 0.5)
    @iteration += 1
    sleep backoff
    results = send(m, *args, &block)
  end

  reset_backoff

  results
end
reset_backoff() click to toggle source
# File lib/awspec/helper/client_wrap.rb, line 49
def reset_backoff
  @backoff   = @orig_backoff
  @iteration = @orig_iter
end