~ubuntu-branches/ubuntu/wily/ruby-retryable/wily-proposed

« back to all changes in this revision

Viewing changes to lib/retryable.rb

  • Committer: Package Import Robot
  • Author(s): Hleb Valoshka
  • Date: 2015-06-22 16:22:37 UTC
  • Revision ID: package-import@ubuntu.com-20150622162237-1xf7yvad71h84er2
Tags: upstream-2.0.1
ImportĀ upstreamĀ versionĀ 2.0.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
require 'retryable/version'
 
2
require 'retryable/configuration'
 
3
 
 
4
module Retryable
 
5
  class << self
 
6
    # A Retryable configuration object. Must act like a hash and return sensible
 
7
    # values for all Retryable configuration options. See Retryable::Configuration.
 
8
    attr_writer :configuration
 
9
 
 
10
    # Call this method to modify defaults in your initializers.
 
11
    #
 
12
    # @example
 
13
    #   Retryable.configure do |config|
 
14
    #     config.ensure       = Proc.new {}
 
15
    #     config.exception_cb = Proc.new {}
 
16
    #     config.matching     = /.*/
 
17
    #     config.on           = StandardError
 
18
    #     config.sleep        = 1
 
19
    #     config.tries        = 2
 
20
    #   end
 
21
    def configure
 
22
      yield(configuration)
 
23
    end
 
24
 
 
25
    # The configuration object.
 
26
    # @see Retryable.configure
 
27
    def configuration
 
28
      @configuration ||= Configuration.new
 
29
    end
 
30
 
 
31
    def enabled?
 
32
      configuration.enabled?
 
33
    end
 
34
 
 
35
    def enable
 
36
      configuration.enable
 
37
    end
 
38
 
 
39
    def disable
 
40
      configuration.disable
 
41
    end
 
42
 
 
43
    def retryable(options = {}, &block)
 
44
      opts = {
 
45
        :tries        => self.configuration.tries,
 
46
        :sleep        => self.configuration.sleep,
 
47
        :on           => self.configuration.on,
 
48
        :matching     => self.configuration.matching,
 
49
        :ensure       => self.configuration.ensure,
 
50
        :exception_cb => self.configuration.exception_cb
 
51
      }
 
52
 
 
53
      check_for_invalid_options(options, opts)
 
54
      opts.merge!(options)
 
55
 
 
56
      return if opts[:tries] == 0
 
57
 
 
58
      on_exception, tries = [ opts[:on] ].flatten, opts[:tries]
 
59
      retries = 0
 
60
      retry_exception = nil
 
61
 
 
62
      begin
 
63
        return yield retries, retry_exception
 
64
      rescue *on_exception => exception
 
65
        raise unless configuration.enabled?
 
66
        raise unless exception.message =~ opts[:matching]
 
67
        raise if retries+1 >= tries
 
68
 
 
69
        # Interrupt Exception could be raised while sleeping
 
70
        begin
 
71
          Kernel.sleep opts[:sleep].respond_to?(:call) ? opts[:sleep].call(retries) : opts[:sleep]
 
72
        rescue *on_exception
 
73
        end
 
74
 
 
75
        retries += 1
 
76
        retry_exception = exception
 
77
        opts[:exception_cb].call(retry_exception)
 
78
        retry
 
79
      ensure
 
80
        opts[:ensure].call(retries)
 
81
      end
 
82
    end
 
83
 
 
84
    private
 
85
 
 
86
    def check_for_invalid_options(custom_options, default_options)
 
87
      invalid_options = default_options.merge(custom_options).keys - default_options.keys
 
88
 
 
89
      raise ArgumentError.new("[Retryable] Invalid options: #{invalid_options.join(", ")}") unless invalid_options.empty?
 
90
    end
 
91
  end
 
92
end
 
93