class Bogo::Retry

Perform action and retry until successful or abort

Attributes

action[R]

@return [Proc] action to perform

attempts[R]

@return [Integer] number of attempts

dead[R]

@return [TrueClass, FalseClass] retry is dead

description[R]

@return [String] description of action

max_attempts[R]

@return [Integer] maximum number of attempts

ui[R]

@return [Bogo::Ui] UI to direct warnings

Public Class Methods

build(type, *args, &block) click to toggle source

Create a type of retry

@param type [String, Symbol] name of retry type @param args [Object] instantiation arguments @yield instantiation block @return [Retry] specific subclass instance

# File lib/bogo/retry.rb, line 14
def self.build(type, *args, &block)
  klass = self.const_get(Bogo::Utility.camel(type))
  klass.new(*args, &block)
end
new(args={}, &block) click to toggle source

Create a new retry instance

@param args [Hash] @option args [String] :description action description @option args [Bogo::Ui] :ui output failure/retry notifications @option args [Integer] :max_attempts maximum number of retries @return [self]

# File lib/bogo/retry.rb, line 39
def initialize(args={}, &block)
  unless(block)
    raise ArgumentError.new 'Expecting block but no block was provided!'
  end
  args = args.to_smash
  @ui = args[:ui]
  @description = args.fetch(:description, 'Task')
  @max_attempts = args[:max_attempts]
  @action = block
  @attempts = 0
  @dead = false
  run! unless args[:auto_run] == false
end

Public Instance Methods

retries() click to toggle source

@return [Integer]

# File lib/bogo/retry.rb, line 92
def retries
  attempts > 0 ? attempts - 1 : 0
end
run!() { |e| ... } click to toggle source

Run action until success

@yield optional to allow custom exception check @yieldparam [Exception] exception caught @yieldreturn [TrueClass, FalseClass] if retry should be peformed @return [Object] result of action

# File lib/bogo/retry.rb, line 59
def run!
  if(dead)
    raise RuntimeError.new "Action has already reached maximum allowed attempts (#{max_attempts})!"
  else
    begin
      log_attempt!
      action.call
    rescue => e
      if(block_given?)
        raise unless yield(e)
      end
      if(max_attempts.nil? || attempts < max_attempts)
        interval = wait_on_failure(e)
        if(ui)
          if(max_attempts)
            attempt_info = "[Attempt #{attempts}/#{max_attempts}]"
          end
          ui.warn "#{description} failed (#{e.class}: #{e}) - Retry in #{interval.to_i} seconds #{attempt_info}"
        end
        sleep(interval)
        retry
      else
        if(ui && max_attempts.to_i > 0)
          ui.error "#{description} failed (#{e.class}: #{e}) - Maximum number of attempts reached!"
        end
        @dead = true
        raise e
      end
    end
  end
end

Protected Instance Methods

log_attempt!() click to toggle source

@return [Intenger]

# File lib/bogo/retry.rb, line 107
def log_attempt!
  @attempts = attempts.next
end
wait_on_failure(error) click to toggle source

Amount of time to wait

@param error [StandardError] failure exception @return [Numeric] amount of wait time

# File lib/bogo/retry.rb, line 102
def wait_on_failure(error)
  raise NotImplementedError
end