Module: Pester

Defined in:
lib/pester.rb,
lib/pester/config.rb,
lib/pester/version.rb,
lib/pester/behaviors.rb,
lib/pester/behaviors/sleep.rb

Defined Under Namespace

Modules: Behaviors Classes: Config

Constant Summary collapse

VERSION =
'0.1.2'

Class Method Summary collapse

Class Method Details

.configure(&block) ⇒ Object



7
8
9
# File 'lib/pester.rb', line 7

def self.configure(&block)
  Config.configure(&block)
end

.retry(options = {}, &block) ⇒ Object



11
12
13
# File 'lib/pester.rb', line 11

def self.retry(options = {}, &block)
  retry_action(options.merge(on_retry: Behaviors::Sleep::Constant), &block)
end

.retry_action(opts = {}, &block) ⇒ Object

This function executes a block and retries the block depending on which errors were thrown. Retries 4 times by default.

Options:

retry_error_classes       - A single or array of exceptions to retry on. Thrown exceptions not in this list
                            (including parent/sub-classes) will be reraised
retry_error_messages      - A single or array of exception messages to retry on.  If only this options is passed,
                            any exception with a message containing one of these strings will be retried.  If this
                            option is passed along with retry_error_classes, retry will only happen when both the
                            class and the message match the exception.  Strings and regexes are both permitted.
reraise_error_classes     - A single or array of exceptions to always re-raiseon. Thrown exceptions not in
                            this list (including parent/sub-classes) will be retried
max_attempts              - Max number of attempts to retry
delay_interval            - Second interval by which successive attempts will be incremented. A value of 2
                            passed to retry_with_backoff will retry first after 2 seconds, then 4, then 6, et al.
on_retry                  - A Proc to be called on each successive failure, before the next retry
on_max_attempts_exceeded  - A Proc to be called when attempt_num >= max_attempts - 1
logger                    - Where to log the output

Usage:

retry_action(retry_error_classes: [Mysql2::Error]) do
  puts 'trying to remove a directory'
  FileUtils.rm_r(directory)
end


48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/pester.rb', line 48

def self.retry_action(opts = {}, &block)
  merge_defaults(opts)
  if opts[:retry_error_classes] && opts[:reraise_error_classes]
    fail 'You can only have one of retry_error_classes or reraise_error_classes'
  end

  opts[:max_attempts].times do |attempt_num|
    begin
      return yield(block)
    rescue => e
      unless should_retry?(e, opts)
        opts[:logger].warn('Reraising exception from inside retry_action.')
        raise
      end

      if opts[:max_attempts] - 1 > attempt_num
        attempts_left = opts[:max_attempts] - attempt_num - 1
        trace = e.backtrace
        opts[:logger].warn("Failure encountered: #{e}, backing off and trying again #{attempts_left} more times. Trace: #{trace}")
        opts[:on_retry].call(attempt_num, opts[:delay_interval])
      else
        # Careful here because you will get back the return value of the on_max_attempts_exceeded proc!
        return opts[:on_max_attempts_exceeded].call(opts[:logger], opts[:max_attempts], e)
      end
    end
  end

  nil
end

.retry_with_backoff(options = {}, &block) ⇒ Object



15
16
17
# File 'lib/pester.rb', line 15

def self.retry_with_backoff(options = {}, &block)
  retry_action(options.merge(on_retry: Behaviors::Sleep::Linear), &block)
end

.retry_with_exponential_backoff(options = {}, &block) ⇒ Object



19
20
21
# File 'lib/pester.rb', line 19

def self.retry_with_exponential_backoff(options = {}, &block)
  retry_action({ delay_interval: 1 }.merge(options).merge(on_retry: Behaviors::Sleep::Exponential), &block)
end