retryable 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e02743f5a92c56de8d631d1ce21a2bc1b18abacf
4
+ data.tar.gz: 236dafbf366171b840d64a1317ad14becf56c099
5
+ SHA512:
6
+ metadata.gz: a9cbd76de408e65f6b6238de7082c017a2a05278f5f01c38cacc8088929f08ae4266c1c711a8290fb7255d87120fe83295d63cd7758f66ae7332b0cb35ec490a
7
+ data.tar.gz: 89fe460024058360678c483b41e75bc75442446c4698df5623bad47e09b0b5321b5370441595940ce8ef9446c772ed1f37523f55f5014c9a493efdd0da744bd0
@@ -1,3 +1,7 @@
1
+ ## Retryable 2.0.1 ##
2
+
3
+ * Retryable can now be configured globally via Retryable.configure block.
4
+
1
5
  ## Retryable 2.0.0 ##
2
6
 
3
7
  * Retryable can now be used without monkey patching Kernel module(use `Retryable.retryable` instead). Thanks @oppegard
data/README.md CHANGED
@@ -58,6 +58,20 @@ end
58
58
 
59
59
  :tries => 2, :on => StandardError, :sleep => 1, :matching => /.*/, :ensure => Proc.new { }, :exception_cb => Proc.new { }
60
60
 
61
+ Retryable also could be configured globally to change those defaults:
62
+
63
+ ```
64
+ Retryable.configure do |config|
65
+ config.ensure = Proc.new {}
66
+ config.exception_cb = Proc.new {}
67
+ config.matching = /.*/
68
+ config.on = StandardError
69
+ config.sleep = 1
70
+ config.tries = 2
71
+ end
72
+ ```
73
+
74
+
61
75
  Sleeping
62
76
  --------
63
77
  By default Retryable waits for one second between retries. You can change this and even provide your own exponential backoff scheme.
@@ -127,6 +141,7 @@ versions:
127
141
  * Ruby 1.9.3
128
142
  * Ruby 2.0.0
129
143
  * Ruby 2.1.2
144
+ * Ruby 2.2.0
130
145
 
131
146
  If something doesn't work on one of these versions, it's a bug.
132
147
 
@@ -1,46 +1,93 @@
1
1
  require 'retryable/version'
2
- require 'retryable/config'
2
+ require 'retryable/configuration'
3
3
 
4
4
  module Retryable
5
- def self.retryable(options = {}, &block)
6
- opts = {:tries => 2, :sleep => 1, :on => StandardError, :matching => /.*/, :ensure => Proc.new {}, :exception_cb => Proc.new {}}
7
- check_for_invalid_options(options, opts)
8
- opts.merge!(options)
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
9
 
10
- return if opts[:tries] == 0
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
+ }
11
52
 
12
- on_exception, tries = [ opts[:on] ].flatten, opts[:tries]
13
- retries = 0
14
- retry_exception = nil
53
+ check_for_invalid_options(options, opts)
54
+ opts.merge!(options)
15
55
 
16
- begin
17
- return yield retries, retry_exception
18
- rescue *on_exception => exception
19
- raise unless Retryable.enabled?
20
- raise unless exception.message =~ opts[:matching]
21
- raise if retries+1 >= tries
56
+ return if opts[:tries] == 0
57
+
58
+ on_exception, tries = [ opts[:on] ].flatten, opts[:tries]
59
+ retries = 0
60
+ retry_exception = nil
22
61
 
23
- # Interrupt Exception could be raised while sleeping
24
62
  begin
25
- Kernel.sleep opts[:sleep].respond_to?(:call) ? opts[:sleep].call(retries) : opts[:sleep]
26
- rescue *on_exception
27
- end
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
28
68
 
29
- retries += 1
30
- retry_exception = exception
31
- opts[:exception_cb].call(retry_exception)
32
- retry
33
- ensure
34
- opts[:ensure].call(retries)
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
35
82
  end
36
- end
37
83
 
38
- private
84
+ private
39
85
 
40
- def self.check_for_invalid_options(custom_options, default_options)
41
- invalid_options = default_options.merge(custom_options).keys - default_options.keys
86
+ def check_for_invalid_options(custom_options, default_options)
87
+ invalid_options = default_options.merge(custom_options).keys - default_options.keys
42
88
 
43
- raise ArgumentError.new("[Retryable] Invalid options: #{invalid_options.join(", ")}") unless invalid_options.empty?
89
+ raise ArgumentError.new("[Retryable] Invalid options: #{invalid_options.join(", ")}") unless invalid_options.empty?
90
+ end
44
91
  end
45
92
  end
46
93
 
@@ -0,0 +1,65 @@
1
+ module Retryable
2
+ # Used to set up and modify settings for the retryable.
3
+ class Configuration
4
+ OPTIONS = [
5
+ :ensure,
6
+ :exception_cb,
7
+ :matching,
8
+ :on,
9
+ :sleep,
10
+ :tries
11
+ ].freeze
12
+
13
+ attr_accessor :ensure
14
+ attr_accessor :exception_cb
15
+ attr_accessor :matching
16
+ attr_accessor :on
17
+ attr_accessor :sleep
18
+ attr_accessor :tries
19
+
20
+ attr_accessor :enabled
21
+
22
+ alias_method :enabled?, :enabled
23
+
24
+ def initialize
25
+ @ensure = Proc.new {}
26
+ @exception_cb = Proc.new {}
27
+ @matching = /.*/
28
+ @on = StandardError
29
+ @sleep = 1
30
+ @tries = 2
31
+
32
+ @enabled = true
33
+ end
34
+
35
+ def enable
36
+ @enabled = true
37
+ end
38
+
39
+ def disable
40
+ @enabled = false
41
+ end
42
+
43
+ # Allows config options to be read like a hash
44
+ #
45
+ # @param [Symbol] option Key for a given attribute
46
+ def [](option)
47
+ send(option)
48
+ end
49
+
50
+ # Returns a hash of all configurable options
51
+ def to_hash
52
+ OPTIONS.inject({}) do |hash, option|
53
+ hash[option.to_sym] = self.send(option)
54
+ hash
55
+ end
56
+ end
57
+
58
+ # Returns a hash of all configurable options merged with +hash+
59
+ #
60
+ # @param [Hash] hash A set of configuration options that will take precedence over the defaults
61
+ def merge(hash)
62
+ to_hash.merge(hash)
63
+ end
64
+ end
65
+ end
@@ -2,7 +2,7 @@ module Retryable
2
2
  class Version
3
3
  MAJOR = 2 unless defined? Retryable::Version::MAJOR
4
4
  MINOR = 0 unless defined? Retryable::Version::MINOR
5
- PATCH = 0 unless defined? Retryable::Version::PATCH
5
+ PATCH = 1 unless defined? Retryable::Version::PATCH
6
6
 
7
7
  class << self
8
8
 
@@ -4,7 +4,7 @@ require File.expand_path('../lib/retryable/version', __FILE__)
4
4
  Gem::Specification.new do |gem|
5
5
  gem.add_development_dependency 'bundler', '~> 1.0'
6
6
  gem.authors = ["Nikita Fedyashev", "Carlo Zottmann", "Chu Yeow"]
7
- gem.description = %q{Kernel#retryable, allow for retrying of code blocks.}
7
+ gem.description = %q{Retryable#retryable, allow for retrying of code blocks.}
8
8
  gem.email = %q{loci.master@gmail.com}
9
9
  gem.files = %w(CHANGELOG.md LICENSE.md README.md Rakefile retryable.gemspec)
10
10
  gem.files += Dir.glob("lib/**/*.rb")
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Retryable do
4
+ it 'is enabled by default' do
5
+ expect(Retryable).to be_enabled
6
+ end
7
+
8
+ it 'could be disabled' do
9
+ Retryable.disable
10
+ expect(Retryable).not_to be_enabled
11
+ end
12
+
13
+ context 'when disabled' do
14
+ before do
15
+ Retryable.disable
16
+ end
17
+
18
+ it 'could be re-enabled' do
19
+ Retryable.enable
20
+ expect(Retryable).to be_enabled
21
+ end
22
+ end
23
+
24
+ context 'when configured globally with custom sleep parameter' do
25
+ it 'passes retry count and exception on retry' do
26
+ expect(Kernel).to receive(:sleep).once.with(3)
27
+
28
+ Retryable.configure do |config|
29
+ config.sleep = 3
30
+ end
31
+
32
+ count_retryable(:tries => 2) do |tries, ex|
33
+ expect(ex.class).to eq(StandardError) if tries > 0
34
+ raise StandardError if tries < 1
35
+ end
36
+ expect(@try_count).to eq(2)
37
+ end
38
+ end
39
+ end
@@ -4,6 +4,10 @@ require 'rspec'
4
4
  RSpec.configure do |config|
5
5
  config.disable_monkey_patching!
6
6
 
7
+ config.before(:each) do
8
+ reset_config
9
+ end
10
+
7
11
  def count_retryable(*opts)
8
12
  @try_count = 0
9
13
  return Retryable.retryable(*opts) do |*args|
@@ -11,4 +15,10 @@ RSpec.configure do |config|
11
15
  yield *args
12
16
  end
13
17
  end
18
+
19
+ private
20
+
21
+ def reset_config
22
+ Retryable.configuration = nil
23
+ end
14
24
  end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: retryable
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
5
- prerelease:
4
+ version: 2.0.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Nikita Fedyashev
@@ -11,25 +10,23 @@ authors:
11
10
  autorequire:
12
11
  bindir: bin
13
12
  cert_chain: []
14
- date: 2014-12-03 00:00:00.000000000 Z
13
+ date: 2015-01-30 00:00:00.000000000 Z
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
16
  name: bundler
18
17
  requirement: !ruby/object:Gem::Requirement
19
- none: false
20
18
  requirements:
21
- - - ~>
19
+ - - "~>"
22
20
  - !ruby/object:Gem::Version
23
21
  version: '1.0'
24
22
  type: :development
25
23
  prerelease: false
26
24
  version_requirements: !ruby/object:Gem::Requirement
27
- none: false
28
25
  requirements:
29
- - - ~>
26
+ - - "~>"
30
27
  - !ruby/object:Gem::Version
31
28
  version: '1.0'
32
- description: Kernel#retryable, allow for retrying of code blocks.
29
+ description: Retryable#retryable, allow for retrying of code blocks.
33
30
  email: loci.master@gmail.com
34
31
  executables: []
35
32
  extensions: []
@@ -39,39 +36,38 @@ files:
39
36
  - LICENSE.md
40
37
  - README.md
41
38
  - Rakefile
42
- - retryable.gemspec
43
- - lib/retryable/config.rb
44
- - lib/retryable/version.rb
45
39
  - lib/retryable.rb
46
- - spec/lib/config_spec.rb
40
+ - lib/retryable/configuration.rb
41
+ - lib/retryable/version.rb
42
+ - retryable.gemspec
43
+ - spec/lib/configuration_spec.rb
47
44
  - spec/lib/retryable_spec.rb
48
45
  - spec/spec_helper.rb
49
46
  homepage: http://github.com/nfedyashev/retryable
50
47
  licenses: []
48
+ metadata: {}
51
49
  post_install_message:
52
50
  rdoc_options: []
53
51
  require_paths:
54
52
  - lib
55
53
  required_ruby_version: !ruby/object:Gem::Requirement
56
- none: false
57
54
  requirements:
58
- - - ! '>='
55
+ - - ">="
59
56
  - !ruby/object:Gem::Version
60
57
  version: '0'
61
58
  required_rubygems_version: !ruby/object:Gem::Requirement
62
- none: false
63
59
  requirements:
64
- - - ! '>='
60
+ - - ">="
65
61
  - !ruby/object:Gem::Version
66
62
  version: 1.3.6
67
63
  requirements: []
68
64
  rubyforge_project:
69
- rubygems_version: 1.8.23
65
+ rubygems_version: 2.4.5
70
66
  signing_key:
71
- specification_version: 3
72
- summary: Kernel#retryable, allow for retrying of code blocks.
67
+ specification_version: 4
68
+ summary: Retryable#retryable, allow for retrying of code blocks.
73
69
  test_files:
74
- - spec/lib/config_spec.rb
70
+ - spec/lib/configuration_spec.rb
75
71
  - spec/lib/retryable_spec.rb
76
72
  - spec/spec_helper.rb
77
73
  has_rdoc:
@@ -1,16 +0,0 @@
1
- module Retryable
2
- @enabled = true
3
- class << self; attr_accessor :enabled; end
4
-
5
- def self.enable
6
- @enabled = true
7
- end
8
-
9
- def self.disable
10
- @enabled = false
11
- end
12
-
13
- def self.enabled?
14
- !!@enabled
15
- end
16
- end
@@ -1,23 +0,0 @@
1
- require 'spec_helper'
2
-
3
- RSpec.describe Retryable do
4
- it 'is enabled by default' do
5
- expect(Retryable).to be_enabled
6
- end
7
-
8
- it 'could be disabled' do
9
- Retryable.disable
10
- expect(Retryable).not_to be_enabled
11
- end
12
-
13
- context 'when disabled' do
14
- before do
15
- Retryable.disable
16
- end
17
-
18
- it 'could be re-enabled' do
19
- Retryable.enable
20
- expect(Retryable).to be_enabled
21
- end
22
- end
23
- end