retryable 1.2.5 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +10 -5
- data/lib/retryable.rb +14 -6
- data/spec/lib/retryable_spec.rb +17 -0
- metadata +42 -74
data/README.markdown
CHANGED
@@ -9,7 +9,7 @@ Description
|
|
9
9
|
Runs a code block, and retries it when an exception occurs. It's great when
|
10
10
|
working with flakey webservices (for example).
|
11
11
|
|
12
|
-
It's configured using
|
12
|
+
It's configured using four optional parameters --`:tries`, `:on`, `:sleep`, `:matching`--, and
|
13
13
|
runs the passed block. Should an exception occur, it'll retry for (n-1) times.
|
14
14
|
|
15
15
|
Should the number of retries be reached without success, the last exception
|
@@ -43,7 +43,7 @@ end
|
|
43
43
|
|
44
44
|
## Defaults
|
45
45
|
|
46
|
-
:tries => 2, :on =>
|
46
|
+
:tries => 2, :on => StandardError, :sleep => 1, :matching => /.*/
|
47
47
|
|
48
48
|
Sleeping
|
49
49
|
--------
|
@@ -58,8 +58,9 @@ retryable(:sleep => lambda { |n| 4**n }) { } # sleep 1, 4, 16, etc. each try
|
|
58
58
|
Matching error messages
|
59
59
|
--------
|
60
60
|
You can also retry based on the exception message:
|
61
|
+
|
61
62
|
```
|
62
|
-
|
63
|
+
retryable(:matching => /IO timeout/) do |retries, exception|
|
63
64
|
raise "yo, IO timeout!" if retries == 0
|
64
65
|
end
|
65
66
|
```
|
@@ -67,6 +68,7 @@ end
|
|
67
68
|
Block Parameters
|
68
69
|
--------
|
69
70
|
Your block is called with two optional parameters: the number of tries until now, and the most recent exception.
|
71
|
+
|
70
72
|
```
|
71
73
|
retryable do |retries, exception|
|
72
74
|
puts "try #{retries} failed with exception: #{exception}" if retries > 0
|
@@ -92,6 +94,8 @@ gem 'retryable'
|
|
92
94
|
|
93
95
|
## Changelog
|
94
96
|
|
97
|
+
* v1.3.0: StandardError is now default exception for rescuing.
|
98
|
+
* v1.2.5: became friendly to any rubygems version installed
|
95
99
|
* v1.2.4: added :matching option + better options validation
|
96
100
|
* v1.2.3: fixed dependencies
|
97
101
|
* v1.2.2: added :sleep option
|
@@ -101,6 +105,7 @@ gem 'retryable'
|
|
101
105
|
|
102
106
|
## Thanks
|
103
107
|
|
104
|
-
|
105
|
-
|
108
|
+
[Chu Yeow for this nifty piece of code](http://blog.codefront.net/2008/01/14/retrying-code-blocks-in-ruby-on-exceptions-whatever/)
|
109
|
+
[Scott Bronson](https://github.com/bronson/retryable)
|
110
|
+
|
106
111
|
|
data/lib/retryable.rb
CHANGED
@@ -3,22 +3,30 @@ module Kernel
|
|
3
3
|
class InvalidRetryableOptions < RuntimeError; end
|
4
4
|
|
5
5
|
def retryable(options = {}, &block)
|
6
|
-
opts = { :tries => 2, :sleep => 1, :on =>
|
6
|
+
opts = { :tries => 2, :sleep => 1, :on => StandardError, :matching => /.*/ }
|
7
7
|
check_for_invalid_options(options, opts)
|
8
8
|
opts.merge!(options)
|
9
9
|
|
10
10
|
return nil if opts[:tries] == 0
|
11
11
|
|
12
|
-
|
12
|
+
on_exception, tries = [ opts[:on] ].flatten, opts[:tries]
|
13
13
|
retries = 0
|
14
|
-
|
14
|
+
retry_exception = nil
|
15
|
+
|
15
16
|
begin
|
16
|
-
return yield retries
|
17
|
-
rescue *
|
17
|
+
return yield retries, retry_exception
|
18
|
+
rescue *on_exception => exception
|
18
19
|
raise unless exception.message =~ opts[:matching]
|
19
20
|
raise if retries+1 >= opts[:tries]
|
20
|
-
|
21
|
+
|
22
|
+
# Interrupt Exception could be raised while sleeping
|
23
|
+
begin
|
24
|
+
sleep opts[:sleep].respond_to?(:call) ? opts[:sleep].call(retries) : opts[:sleep]
|
25
|
+
rescue *on_exception
|
26
|
+
end
|
27
|
+
|
21
28
|
retries += 1
|
29
|
+
retry_exception = exception
|
22
30
|
retry
|
23
31
|
end
|
24
32
|
end
|
data/spec/lib/retryable_spec.rb
CHANGED
@@ -6,6 +6,13 @@ describe 'retryable' do
|
|
6
6
|
@attempt = 0
|
7
7
|
end
|
8
8
|
|
9
|
+
it "should only catch StandardError by default" do
|
10
|
+
lambda do
|
11
|
+
count_retryable(:tries => 2) { |tries, ex| raise Exception if tries < 1 }
|
12
|
+
end.should raise_error Exception
|
13
|
+
@try_count.should == 1
|
14
|
+
end
|
15
|
+
|
9
16
|
it "should retry on default exception" do
|
10
17
|
Kernel.should_receive(:sleep).once.with(1)
|
11
18
|
|
@@ -13,6 +20,16 @@ describe 'retryable' do
|
|
13
20
|
@try_count.should == 2
|
14
21
|
end
|
15
22
|
|
23
|
+
it "should pass retry count and exception on retry" do
|
24
|
+
Kernel.should_receive(:sleep).once.with(1)
|
25
|
+
|
26
|
+
count_retryable(:tries => 2) do |tries, ex|
|
27
|
+
ex.class.should == StandardError if tries > 0
|
28
|
+
raise StandardError if tries < 1
|
29
|
+
end
|
30
|
+
@try_count.should == 2
|
31
|
+
end
|
32
|
+
|
16
33
|
it "should make another try if exception is covered by :on" do
|
17
34
|
Kernel.stub!(:sleep)
|
18
35
|
count_retryable(:on => [StandardError, ArgumentError, RuntimeError] ) { |tries, ex| raise ArgumentError if tries < 1 }
|
metadata
CHANGED
@@ -1,119 +1,87 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: retryable
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.3.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 1
|
8
|
-
- 2
|
9
|
-
- 5
|
10
|
-
version: 1.2.5
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Nikita Fedyashev
|
14
9
|
- Carlo Zottmann
|
15
10
|
- Chu Yeow
|
16
11
|
autorequire:
|
17
12
|
bindir: bin
|
18
13
|
cert_chain: []
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
- !ruby/object:Gem::Dependency
|
14
|
+
date: 2011-05-17 00:00:00.000000000 Z
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
23
17
|
name: rspec
|
24
|
-
|
25
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
18
|
+
requirement: &2157041380 !ruby/object:Gem::Requirement
|
26
19
|
none: false
|
27
|
-
requirements:
|
20
|
+
requirements:
|
28
21
|
- - ~>
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
|
31
|
-
segments:
|
32
|
-
- 2
|
33
|
-
- 5
|
34
|
-
- 0
|
35
|
-
version: 2.5.0
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.10.0
|
36
24
|
type: :development
|
37
|
-
version_requirements: *id001
|
38
|
-
- !ruby/object:Gem::Dependency
|
39
|
-
name: autotest
|
40
25
|
prerelease: false
|
41
|
-
|
26
|
+
version_requirements: *2157041380
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: autotest
|
29
|
+
requirement: &2157040720 !ruby/object:Gem::Requirement
|
42
30
|
none: false
|
43
|
-
requirements:
|
31
|
+
requirements:
|
44
32
|
- - ~>
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
hash: 35
|
47
|
-
segments:
|
48
|
-
- 4
|
49
|
-
- 4
|
50
|
-
- 6
|
33
|
+
- !ruby/object:Gem::Version
|
51
34
|
version: 4.4.6
|
52
35
|
type: :development
|
53
|
-
version_requirements: *id002
|
54
|
-
- !ruby/object:Gem::Dependency
|
55
|
-
name: bundler
|
56
36
|
prerelease: false
|
57
|
-
|
37
|
+
version_requirements: *2157040720
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: bundler
|
40
|
+
requirement: &2157040080 !ruby/object:Gem::Requirement
|
58
41
|
none: false
|
59
|
-
requirements:
|
60
|
-
- -
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
|
63
|
-
segments:
|
64
|
-
- 0
|
65
|
-
version: "0"
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
66
46
|
type: :development
|
67
|
-
|
47
|
+
prerelease: false
|
48
|
+
version_requirements: *2157040080
|
68
49
|
description: Kernel#retryable, allow for retrying of code blocks.
|
69
50
|
email: loci.master@gmail.com
|
70
51
|
executables: []
|
71
|
-
|
72
52
|
extensions: []
|
73
|
-
|
74
|
-
extra_rdoc_files:
|
53
|
+
extra_rdoc_files:
|
75
54
|
- README.markdown
|
76
|
-
files:
|
55
|
+
files:
|
77
56
|
- lib/retryable.rb
|
78
57
|
- README.markdown
|
79
58
|
- spec/lib/retryable_spec.rb
|
80
59
|
- spec/spec_helper.rb
|
81
60
|
homepage: http://github.com/nfedyashev/retryable
|
82
|
-
licenses:
|
61
|
+
licenses:
|
83
62
|
- MIT
|
84
63
|
post_install_message:
|
85
64
|
rdoc_options: []
|
86
|
-
|
87
|
-
require_paths:
|
65
|
+
require_paths:
|
88
66
|
- lib
|
89
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
68
|
none: false
|
91
|
-
requirements:
|
92
|
-
- -
|
93
|
-
- !ruby/object:Gem::Version
|
94
|
-
|
95
|
-
|
96
|
-
- 0
|
97
|
-
version: "0"
|
98
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ! '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
74
|
none: false
|
100
|
-
requirements:
|
101
|
-
- -
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
hash: 23
|
104
|
-
segments:
|
105
|
-
- 1
|
106
|
-
- 3
|
107
|
-
- 6
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
108
78
|
version: 1.3.6
|
109
79
|
requirements: []
|
110
|
-
|
111
80
|
rubyforge_project:
|
112
|
-
rubygems_version: 1.
|
81
|
+
rubygems_version: 1.8.17
|
113
82
|
signing_key:
|
114
83
|
specification_version: 3
|
115
84
|
summary: Kernel#retryable, allow for retrying of code blocks.
|
116
|
-
test_files:
|
85
|
+
test_files:
|
117
86
|
- spec/lib/retryable_spec.rb
|
118
87
|
- spec/spec_helper.rb
|
119
|
-
has_rdoc:
|