retriable 1.3.3.1 → 1.4.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/CHANGELOG.md +6 -0
- data/LICENSE +1 -1
- data/README.md +32 -26
- data/lib/retriable.rb +4 -3
- data/lib/retriable/core_ext/kernel.rb +3 -6
- data/lib/retriable/dsl.rb +17 -0
- data/lib/retriable/{retriable.rb → retry.rb} +0 -17
- data/lib/retriable/version.rb +1 -3
- data/retriable.gemspec +1 -0
- data/test/retriable_test.rb +8 -3
- metadata +12 -5
- data/lib/retriable/no_kernel.rb +0 -4
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
## 1.4.0
|
2
|
+
* By default, retriable doesn't monkey patch `Kernel`. If you want this functionality,
|
3
|
+
you can `require 'retriable/core_ext/kernel'.
|
4
|
+
* Upgrade minitest to 5.x.
|
5
|
+
* Refactor the DSL into it's own class.
|
6
|
+
|
1
7
|
## 1.3.3.1
|
2
8
|
* Allow sleep parameter to be a proc/lambda to allow for exponential backoff.
|
3
9
|
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,13 +1,12 @@
|
|
1
|
-
Retriable
|
2
|
-
============
|
1
|
+
#Retriable
|
3
2
|
|
4
3
|
[](http://travis-ci.org/kamui/retriable)
|
5
4
|
|
6
5
|
Retriable is an simple DSL to retry a code block if an exception should be raised. This is especially useful when interacting external api/services or file system calls.
|
7
6
|
|
8
|
-
Installation
|
9
|
-
|
10
|
-
|
7
|
+
##Installation
|
8
|
+
|
9
|
+
via command line:
|
11
10
|
|
12
11
|
```ruby
|
13
12
|
gem install retriable
|
@@ -25,8 +24,7 @@ In your Gemfile:
|
|
25
24
|
gem 'retriable'
|
26
25
|
```
|
27
26
|
|
28
|
-
Usage
|
29
|
-
---------------
|
27
|
+
##Usage
|
30
28
|
|
31
29
|
Code in a retriable block will be retried if an exception is raised. By default, Retriable will rescue any exception inherited from `StandardError` (and `Timeout::Error`, which does not inherit from `StandardError` in ruby 1.8) and make 3 retry attempts before raising the last exception.
|
32
30
|
|
@@ -36,13 +34,15 @@ require 'retriable'
|
|
36
34
|
class Api
|
37
35
|
# Use it in methods that interact with unreliable services
|
38
36
|
def get
|
39
|
-
retriable do
|
37
|
+
Retriable.retriable do
|
40
38
|
# code here...
|
41
39
|
end
|
42
40
|
end
|
43
41
|
end
|
44
42
|
```
|
45
43
|
|
44
|
+
###Options
|
45
|
+
|
46
46
|
Here are the available options:
|
47
47
|
|
48
48
|
`tries` (default: 3) - Number of attempts to make at running your code block
|
@@ -58,7 +58,7 @@ Here are the available options:
|
|
58
58
|
You can pass options via an options `Hash`. This example will only retry on a `Timeout::Error`, retry 3 times and sleep for a full second before each attempt.
|
59
59
|
|
60
60
|
```ruby
|
61
|
-
retriable :on => Timeout::Error, :tries => 3, :interval => 1 do
|
61
|
+
Retriable.retriable :on => Timeout::Error, :tries => 3, :interval => 1 do
|
62
62
|
# code here...
|
63
63
|
end
|
64
64
|
```
|
@@ -66,7 +66,7 @@ end
|
|
66
66
|
You can also specify multiple errors to retry on by passing an array of exceptions.
|
67
67
|
|
68
68
|
```ruby
|
69
|
-
retriable :on => [Timeout::Error, Errno::ECONNRESET] do
|
69
|
+
Retriable.retriable :on => [Timeout::Error, Errno::ECONNRESET] do
|
70
70
|
# code here...
|
71
71
|
end
|
72
72
|
```
|
@@ -74,7 +74,7 @@ end
|
|
74
74
|
You can also specify a timeout if you want the code block to only make an attempt for X amount of seconds. This timeout is per attempt.
|
75
75
|
|
76
76
|
```ruby
|
77
|
-
retriable :timeout => 1 do
|
77
|
+
Retriable.retriable :timeout => 1 do
|
78
78
|
# code here...
|
79
79
|
end
|
80
80
|
```
|
@@ -82,19 +82,22 @@ end
|
|
82
82
|
If you need millisecond units of time for the sleep or the timeout:
|
83
83
|
|
84
84
|
```ruby
|
85
|
-
retriable :interval => (200/1000.0), :timeout => (500/1000.0) do
|
85
|
+
Retriable.retriable :interval => (200/1000.0), :timeout => (500/1000.0) do
|
86
86
|
# code here...
|
87
87
|
end
|
88
88
|
```
|
89
89
|
|
90
|
+
###Exponential Backoff
|
91
|
+
|
90
92
|
If you'd like exponential backoff, interval can take a Proc
|
91
93
|
|
92
94
|
```ruby
|
93
95
|
# with exponential back-off - sleep 4, 16, 64, 256, give up
|
94
|
-
retryable :times => 4, :interval => lambda {|attempts| 4 ** attempts} do
|
96
|
+
Retriable.retryable :times => 4, :interval => lambda {|attempts| 4 ** attempts} do
|
95
97
|
# code here...
|
96
98
|
end
|
97
99
|
```
|
100
|
+
###Callbacks
|
98
101
|
|
99
102
|
Retriable also provides a callback called `:on_retry` that will run after an exception is rescued. This callback provides the number of `tries`, and the `exception` that was raised in the current attempt. As these are specified in a `Proc`, unnecessary variables can be left out of the parameter list.
|
100
103
|
|
@@ -103,16 +106,18 @@ do_this_on_each_retry = Proc.new do |exception, tries|
|
|
103
106
|
log "#{exception.class}: '#{exception.message}' - #{tries} attempts."}
|
104
107
|
end
|
105
108
|
|
106
|
-
retriable :on_retry => do_this_on_each_retry do
|
109
|
+
Retriable.retriable :on_retry => do_this_on_each_retry do
|
107
110
|
# code here...
|
108
111
|
end
|
109
112
|
```
|
110
113
|
|
114
|
+
###Ensure/Else
|
115
|
+
|
111
116
|
What if I want to execute a code block at the end, whether or not an exception was rescued ([ensure](http://ruby-doc.org/docs/keywords/1.9/Object.html#method-i-ensure))? Or, what if I want to execute a code block if no exception is raised ([else](http://ruby-doc.org/docs/keywords/1.9/Object.html#method-i-else))? Instead of providing more callbacks, I recommend you just wrap retriable in a begin/retry/else/ensure block:
|
112
117
|
|
113
118
|
```ruby
|
114
119
|
begin
|
115
|
-
retriable do
|
120
|
+
Retriable.retriable do
|
116
121
|
# some code
|
117
122
|
end
|
118
123
|
rescue => e
|
@@ -124,30 +129,31 @@ ensure
|
|
124
129
|
end
|
125
130
|
```
|
126
131
|
|
127
|
-
|
128
|
-
|
129
|
-
|
132
|
+
##Kernel Extension
|
133
|
+
|
134
|
+
If you want to call `Retriable.retriable` without the `Retriable` module prefix and you don't mind extending `Kernel`,
|
135
|
+
there is a kernel extension available for this.
|
136
|
+
|
137
|
+
In your ruby script:
|
130
138
|
|
131
139
|
```ruby
|
132
|
-
|
140
|
+
require 'retriable/core_ext/kernel'
|
133
141
|
```
|
134
142
|
|
135
|
-
|
143
|
+
or in your Gemfile:
|
136
144
|
|
137
145
|
```ruby
|
138
|
-
require 'retriable/
|
146
|
+
gem 'retriable', require: 'retriable/core_ext/kernel'
|
139
147
|
```
|
140
148
|
|
141
|
-
|
149
|
+
and then you can call `retriable` in any context like this:
|
142
150
|
|
143
151
|
```ruby
|
144
|
-
|
152
|
+
retriable do
|
145
153
|
# code here...
|
146
154
|
end
|
147
155
|
```
|
148
156
|
|
149
|
-
|
150
|
-
Credits
|
151
|
-
-------
|
157
|
+
##Credits
|
152
158
|
|
153
159
|
Retriable was originally forked from the retryable-rb gem by [Robert Sosinski](https://github.com/robertsosinski), which in turn originally inspired by code written by [Michael Celona](http://github.com/mcelona) and later assisted by [David Malin](http://github.com/dmalin). The [attempt](https://rubygems.org/gems/attempt) gem by Daniel J. Berger was also an inspiration.
|
data/lib/retriable.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'retriable/retry'
|
2
|
+
|
3
|
+
module Retriable
|
4
|
+
module DSL
|
5
|
+
def retriable(opts = {}, &block)
|
6
|
+
raise LocalJumpError unless block_given?
|
7
|
+
|
8
|
+
Retry.new do |r|
|
9
|
+
r.tries = opts[:tries] if opts[:tries]
|
10
|
+
r.on = opts[:on] if opts[:on]
|
11
|
+
r.interval = opts[:interval] if opts[:interval]
|
12
|
+
r.timeout = opts[:timeout] if opts[:timeout]
|
13
|
+
r.on_retry = opts[:on_retry] if opts[:on_retry]
|
14
|
+
end.perform(&block)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,10 +1,6 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
require 'timeout'
|
4
2
|
|
5
3
|
module Retriable
|
6
|
-
extend self
|
7
|
-
|
8
4
|
class Retry
|
9
5
|
attr_accessor :tries
|
10
6
|
attr_accessor :interval
|
@@ -35,7 +31,6 @@ module Retriable
|
|
35
31
|
if @tries > 0
|
36
32
|
count += 1
|
37
33
|
@on_retry.call(exception, count) if @on_retry
|
38
|
-
|
39
34
|
sleep_for = @interval.respond_to?(:call) ? @interval.call(count) : @interval
|
40
35
|
sleep sleep_for if sleep_for > 0
|
41
36
|
|
@@ -46,16 +41,4 @@ module Retriable
|
|
46
41
|
end
|
47
42
|
end
|
48
43
|
end
|
49
|
-
|
50
|
-
def retriable(opts = {}, &block)
|
51
|
-
raise 'no block given' unless block_given?
|
52
|
-
|
53
|
-
Retry.new do |r|
|
54
|
-
r.tries = opts[:tries] if opts[:tries]
|
55
|
-
r.on = opts[:on] if opts[:on]
|
56
|
-
r.interval = opts[:interval] if opts[:interval]
|
57
|
-
r.timeout = opts[:timeout] if opts[:timeout]
|
58
|
-
r.on_retry = opts[:on_retry] if opts[:on_retry]
|
59
|
-
end.perform(&block)
|
60
|
-
end
|
61
44
|
end
|
data/lib/retriable/version.rb
CHANGED
data/retriable.gemspec
CHANGED
@@ -12,6 +12,7 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.homepage = %q{http://github.com/kamui/retriable}
|
13
13
|
s.summary = %q{Retriable is an simple DSL to retry a code block if an exception should be raised.}
|
14
14
|
s.description = %q{Retriable is an simple DSL to retry a code block if an exception should be raised. This is especially useful when interacting external api/services or file system calls.}
|
15
|
+
s.license = "MIT"
|
15
16
|
|
16
17
|
s.rubyforge_project = "retriable"
|
17
18
|
|
data/test/retriable_test.rb
CHANGED
@@ -1,9 +1,14 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
require 'retriable'
|
2
|
+
require 'retriable/core_ext/kernel'
|
4
3
|
require 'minitest/autorun'
|
5
4
|
|
6
|
-
class RetriableTest <
|
5
|
+
class RetriableTest < Minitest::Test
|
6
|
+
def test_raise_no_block
|
7
|
+
assert_raises LocalJumpError do
|
8
|
+
retriable :on => StandardError
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
7
12
|
def test_without_arguments
|
8
13
|
i = 0
|
9
14
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: retriable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-09-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -61,13 +61,14 @@ files:
|
|
61
61
|
- Rakefile
|
62
62
|
- lib/retriable.rb
|
63
63
|
- lib/retriable/core_ext/kernel.rb
|
64
|
-
- lib/retriable/
|
65
|
-
- lib/retriable/
|
64
|
+
- lib/retriable/dsl.rb
|
65
|
+
- lib/retriable/retry.rb
|
66
66
|
- lib/retriable/version.rb
|
67
67
|
- retriable.gemspec
|
68
68
|
- test/retriable_test.rb
|
69
69
|
homepage: http://github.com/kamui/retriable
|
70
|
-
licenses:
|
70
|
+
licenses:
|
71
|
+
- MIT
|
71
72
|
post_install_message:
|
72
73
|
rdoc_options: []
|
73
74
|
require_paths:
|
@@ -78,12 +79,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
78
79
|
- - ! '>='
|
79
80
|
- !ruby/object:Gem::Version
|
80
81
|
version: '0'
|
82
|
+
segments:
|
83
|
+
- 0
|
84
|
+
hash: -2391393966112040014
|
81
85
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
86
|
none: false
|
83
87
|
requirements:
|
84
88
|
- - ! '>='
|
85
89
|
- !ruby/object:Gem::Version
|
86
90
|
version: '0'
|
91
|
+
segments:
|
92
|
+
- 0
|
93
|
+
hash: -2391393966112040014
|
87
94
|
requirements: []
|
88
95
|
rubyforge_project: retriable
|
89
96
|
rubygems_version: 1.8.25
|
data/lib/retriable/no_kernel.rb
DELETED