class Attempt

The Attempt class encapsulates methods related to multiple attempts at running the same method before actually failing.

Constants

VERSION

The version of the attempt library.

Attributes

increment[RW]

If set, this increments the interval with each failed attempt by that number of seconds.

interval[RW]

Number of seconds to wait between attempts. The default is 60.

level[RW]

Determines which exception level to check when looking for errors to retry. The default is ‘Exception’ (i.e. all errors).

log[RW]

If you provide an IO handle to this option then errors that would have been raised are sent to that handle.

timeout[RW]

If set, the code block is further wrapped in a timeout block.

tries[RW]

Number of attempts to make before failing. The default is 3.

warnings[RW]

A boolean value that determines whether errors that would have been raised should be sent to STDERR as warnings. The default is true.

Public Class Methods

new(**kwargs) click to toggle source

Creates and returns a new Attempt object. The supported keyword options are as follows:

  • tries - The number of attempts to make before giving up. The default is 3.

  • interval - The delay in seconds between each attempt. The default is 60.

  • log - An IO handle or Logger instance where warnings/errors are logged to. The default is nil.

  • increment - The amount to increment the interval between tries. The default is 0.

  • level - The level of exception to be caught. The default is everything, i.e. Exception.

  • warnings - Boolean value that indicates whether or not errors are treated as warnings

    until the maximum number of attempts has been made. The default is true.
  • timeout - Boolean value to indicate whether or not to automatically wrap your

    proc in a Timeout/SafeTimeout block. The default is false.

Example:

a = Attempt.new(tries: 5, increment: 10, timeout: true)
a.attempt{ http.get("http://something.foo.com") }
# File lib/attempt.rb, line 67
def initialize(**options)
  @tries     = options[:tries] || 3         # Reasonable default
  @interval  = options[:interval] || 60     # Reasonable default
  @log       = options[:log]                # Should be an IO handle, if provided
  @increment = options[:increment] || 0     # Should be an integer, if provided
  @timeout   = options[:timeout] || false   # Wrap the code in a timeout block if provided
  @level     = options[:level] || Exception # Level of exception to be caught
  @warnings  = options[:warnings] || true   # Errors are sent to STDERR as warnings if true
end

Public Instance Methods

attempt() { || ... } click to toggle source

Attempt to perform the operation in the provided block up to tries times, sleeping interval between each try.

You will not typically use this method directly, but the Kernel#attempt method instead.

# File lib/attempt.rb, line 83
def attempt(&block)
  count = 1
  begin
    if @timeout
      File::ALT_SEPARATOR ? Timeout.timeout(@timeout, &block) : SafeTimeout.timeout(@timeout, &block)
    else
      yield
    end
  rescue @level => err
    @tries -= 1
    if @tries > 0
      msg = "Error on attempt # #{count}: #{err}; retrying"
      count += 1
      warn Warning, msg if @warnings

      if @log # Accept an IO or Logger object
        @log.respond_to?(:puts) ? @log.puts(msg) : @log.warn(msg)
      end

      @interval += @increment if @increment
      sleep @interval
      retry
    end
    raise
  end
end