retryable 2.0.0 → 2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +4 -0
- data/README.md +15 -0
- data/lib/retryable.rb +77 -30
- data/lib/retryable/configuration.rb +65 -0
- data/lib/retryable/version.rb +1 -1
- data/retryable.gemspec +1 -1
- data/spec/lib/configuration_spec.rb +39 -0
- data/spec/spec_helper.rb +10 -0
- metadata +16 -20
- data/lib/retryable/config.rb +0 -16
- data/spec/lib/config_spec.rb +0 -23
checksums.yaml
ADDED
@@ -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
|
data/CHANGELOG.md
CHANGED
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
|
|
data/lib/retryable.rb
CHANGED
@@ -1,46 +1,93 @@
|
|
1
1
|
require 'retryable/version'
|
2
|
-
require 'retryable/
|
2
|
+
require 'retryable/configuration'
|
3
3
|
|
4
4
|
module Retryable
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
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
|
-
|
13
|
-
|
14
|
-
retry_exception = nil
|
53
|
+
check_for_invalid_options(options, opts)
|
54
|
+
opts.merge!(options)
|
15
55
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
26
|
-
rescue *on_exception
|
27
|
-
|
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
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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
|
-
|
84
|
+
private
|
39
85
|
|
40
|
-
|
41
|
-
|
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
|
-
|
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
|
data/lib/retryable/version.rb
CHANGED
@@ -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 =
|
5
|
+
PATCH = 1 unless defined? Retryable::Version::PATCH
|
6
6
|
|
7
7
|
class << self
|
8
8
|
|
data/retryable.gemspec
CHANGED
@@ -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{
|
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
|
data/spec/spec_helper.rb
CHANGED
@@ -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.
|
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:
|
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:
|
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
|
-
-
|
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:
|
65
|
+
rubygems_version: 2.4.5
|
70
66
|
signing_key:
|
71
|
-
specification_version:
|
72
|
-
summary:
|
67
|
+
specification_version: 4
|
68
|
+
summary: Retryable#retryable, allow for retrying of code blocks.
|
73
69
|
test_files:
|
74
|
-
- spec/lib/
|
70
|
+
- spec/lib/configuration_spec.rb
|
75
71
|
- spec/lib/retryable_spec.rb
|
76
72
|
- spec/spec_helper.rb
|
77
73
|
has_rdoc:
|
data/lib/retryable/config.rb
DELETED
data/spec/lib/config_spec.rb
DELETED
@@ -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
|