retries 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +10 -9
- data/lib/retries.rb +5 -4
- data/lib/retries/version.rb +1 -1
- data/retries.gemspec +1 -0
- data/test/retries_test.rb +24 -2
- metadata +29 -25
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: dd3d179ec65dd4b129917c3de75d16a2338e976f
|
4
|
+
data.tar.gz: 203b004f805b262a373a6a1f013c179aa830a2a6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6777f2702802e0eb96db8f76bd97bc8e15da966b3a8d78f31d6cdd819c8a3681d6fc4441d583dcd9d85def9f4a66c56da6bcd12a28f732e34c0c007dec591751
|
7
|
+
data.tar.gz: ab72433058a85d5e6d0844f54aeecc22fa70032fe07965c6200c019dc87c2328f423fd3d75b4239120039e316812213f850d5546b19327ce66f5a5b426b6c427
|
data/README.md
CHANGED
@@ -48,12 +48,13 @@ end
|
|
48
48
|
### Handlers
|
49
49
|
|
50
50
|
`with_retries` allows you to pass a custom handler that will be called each time before the block is retried.
|
51
|
-
The handler will be called with
|
52
|
-
number of attempts that have been made thus far)
|
51
|
+
The handler will be called with three arguments: `exception` (the rescued exception), `attempt_number` (the
|
52
|
+
number of attempts that have been made thus far), and `total_delay` (the number of seconds since the start
|
53
|
+
of the time the block was first attempted, including all retries).
|
53
54
|
|
54
55
|
``` ruby
|
55
|
-
handler = Proc.new do |exception, attempt_number|
|
56
|
-
puts "Handler saw a #{exception.class}; retry attempt #{attempt_number}"
|
56
|
+
handler = Proc.new do |exception, attempt_number, total_delay|
|
57
|
+
puts "Handler saw a #{exception.class}; retry attempt #{attempt_number}; #{total_delay} seconds have passed."
|
57
58
|
end
|
58
59
|
with_retries(:max_tries => 5, :handler => handler, :rescue => [RuntimeError, ZeroDivisionError]) do |attempt|
|
59
60
|
(1 / 0) if attempt == 3
|
@@ -61,13 +62,13 @@ with_retries(:max_tries => 5, :handler => handler, :rescue => [RuntimeError, Zer
|
|
61
62
|
end
|
62
63
|
```
|
63
64
|
|
64
|
-
This will print:
|
65
|
+
This will print something like:
|
65
66
|
|
66
67
|
```
|
67
|
-
Handler saw a RuntimeError; retry attempt 1
|
68
|
-
Handler saw a RuntimeError; retry attempt 2
|
69
|
-
Handler saw a ZeroDivisionError; retry attempt 3
|
70
|
-
Handler saw a RuntimeError; retry attempt 4
|
68
|
+
Handler saw a RuntimeError; retry attempt 1; 2.9e-05 seconds have passed.
|
69
|
+
Handler saw a RuntimeError; retry attempt 2; 0.501176 seconds have passed.
|
70
|
+
Handler saw a ZeroDivisionError; retry attempt 3; 1.129921 seconds have passed.
|
71
|
+
Handler saw a RuntimeError; retry attempt 4; 1.886828 seconds have passed.
|
71
72
|
```
|
72
73
|
|
73
74
|
### Delay parameters
|
data/lib/retries.rb
CHANGED
@@ -18,7 +18,8 @@ module Kernel
|
|
18
18
|
# @option options [Float] :base_sleep_seconds (0.5) The starting delay between retries.
|
19
19
|
# @option options [Float] :max_sleep_seconds (1.0) The maximum to which to expand the delay between retries.
|
20
20
|
# @option options [Proc] :handler (nil) If not `nil`, a `Proc` that will be called for each retry. It will be
|
21
|
-
# passed
|
21
|
+
# passed three arguments, `exception` (the rescued exception), `attempt_number`,
|
22
|
+
# and `total_delay` (seconds since start of first attempt).
|
22
23
|
# @option options [Exception, <Exception>] :rescue (StandardError) This may be a specific exception class to
|
23
24
|
# rescue or an array of classes.
|
24
25
|
# @yield [attempt_number] The (required) block to be executed, which is passed the attempt number as a
|
@@ -34,18 +35,18 @@ module Kernel
|
|
34
35
|
raise "#{options_error_string} :base_sleep_seconds cannot be greater than :max_sleep_seconds."
|
35
36
|
end
|
36
37
|
handler = options[:handler]
|
37
|
-
exception_types_to_rescue = options[:rescue] || StandardError
|
38
|
-
exception_types_to_rescue = [exception_types_to_rescue] unless exception_types_to_rescue.is_a?(Array)
|
38
|
+
exception_types_to_rescue = Array(options[:rescue]) || [StandardError]
|
39
39
|
raise "#{options_error_string} with_retries must be passed a block" unless block_given?
|
40
40
|
|
41
41
|
# Let's do this thing
|
42
42
|
attempts = 0
|
43
|
+
start_time = Time.now
|
43
44
|
begin
|
44
45
|
attempts += 1
|
45
46
|
return block.call(attempts)
|
46
47
|
rescue *exception_types_to_rescue => exception
|
47
48
|
raise exception if attempts >= max_tries
|
48
|
-
handler.call(exception, attempts) if handler
|
49
|
+
handler.call(exception, attempts, Time.now - start_time) if handler
|
49
50
|
# Don't sleep at all if sleeping is disabled (used in testing).
|
50
51
|
if Retries.sleep_enabled
|
51
52
|
# The sleep time is an exponentially-increasing function of base_sleep_seconds. But, it never exceeds
|
data/lib/retries/version.rb
CHANGED
data/retries.gemspec
CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |gem|
|
|
18
18
|
# For running the tests
|
19
19
|
gem.add_development_dependency "rake"
|
20
20
|
gem.add_development_dependency "scope"
|
21
|
+
gem.add_development_dependency "rr"
|
21
22
|
|
22
23
|
# For generating the documentation
|
23
24
|
gem.add_development_dependency "yard"
|
data/test/retries_test.rb
CHANGED
@@ -1,10 +1,17 @@
|
|
1
1
|
require "scope"
|
2
2
|
require "minitest/autorun"
|
3
3
|
require "timeout"
|
4
|
+
require "rr"
|
4
5
|
|
5
6
|
$:.unshift File.join(File.dirname(__FILE__), "../lib")
|
6
7
|
require "retries"
|
7
8
|
|
9
|
+
module Scope
|
10
|
+
class TestCase
|
11
|
+
include RR::Adapters::MiniTest
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
8
15
|
class CustomErrorA < RuntimeError; end
|
9
16
|
class CustomErrorB < RuntimeError; end
|
10
17
|
|
@@ -66,8 +73,8 @@ class RetriesTest < Scope::TestCase
|
|
66
73
|
assert_equal exception_handler_run_times, attempt_number
|
67
74
|
assert exception.is_a?(CustomErrorA)
|
68
75
|
end
|
69
|
-
with_retries(:max_tries => 4, :base_sleep_seconds => 0, :max_sleep_seconds => 0,
|
70
|
-
:rescue => CustomErrorA) do
|
76
|
+
with_retries(:max_tries => 4, :base_sleep_seconds => 0, :max_sleep_seconds => 0,
|
77
|
+
:handler => handler, :rescue => CustomErrorA) do
|
71
78
|
tries += 1
|
72
79
|
raise CustomErrorA.new if tries < 4
|
73
80
|
end
|
@@ -75,6 +82,21 @@ class RetriesTest < Scope::TestCase
|
|
75
82
|
assert_equal 3, exception_handler_run_times
|
76
83
|
end
|
77
84
|
|
85
|
+
should "pass total elapsed time to :handler upon each handled exception" do
|
86
|
+
Retries.sleep_enabled = false
|
87
|
+
fake_time = -10
|
88
|
+
stub(Time).now { fake_time += 10 }
|
89
|
+
handler = Proc.new do |exception, attempt_number, total_delay|
|
90
|
+
# Check that the handler is passed the proper total delay time
|
91
|
+
assert_equal fake_time, total_delay
|
92
|
+
end
|
93
|
+
tries = 0
|
94
|
+
with_retries(:max_tries => 3, :handler => handler, :rescue => CustomErrorA) do
|
95
|
+
tries += 1
|
96
|
+
raise CustomErrorA.new if tries < 3
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
78
100
|
should "not sleep if Retries.sleep_enabled is false" do
|
79
101
|
Retries.sleep_enabled = false
|
80
102
|
assert_raises(RuntimeError) do # If we get a Timeout::Error, this won't pass.
|
metadata
CHANGED
@@ -1,78 +1,83 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: retries
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.4
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Caleb Spare
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2013-03-12 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rake
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: scope
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rr
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
44
53
|
- !ruby/object:Gem::Version
|
45
54
|
version: '0'
|
46
55
|
- !ruby/object:Gem::Dependency
|
47
56
|
name: yard
|
48
57
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
58
|
requirements:
|
51
|
-
- -
|
59
|
+
- - '>='
|
52
60
|
- !ruby/object:Gem::Version
|
53
61
|
version: '0'
|
54
62
|
type: :development
|
55
63
|
prerelease: false
|
56
64
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
65
|
requirements:
|
59
|
-
- -
|
66
|
+
- - '>='
|
60
67
|
- !ruby/object:Gem::Version
|
61
68
|
version: '0'
|
62
69
|
- !ruby/object:Gem::Dependency
|
63
70
|
name: redcarpet
|
64
71
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
72
|
requirements:
|
67
|
-
- -
|
73
|
+
- - '>='
|
68
74
|
- !ruby/object:Gem::Version
|
69
75
|
version: '0'
|
70
76
|
type: :development
|
71
77
|
prerelease: false
|
72
78
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
79
|
requirements:
|
75
|
-
- -
|
80
|
+
- - '>='
|
76
81
|
- !ruby/object:Gem::Version
|
77
82
|
version: '0'
|
78
83
|
description: Retries is a gem for retrying blocks with randomized exponential backoff.
|
@@ -94,27 +99,26 @@ files:
|
|
94
99
|
- test/retries_test.rb
|
95
100
|
homepage: https://github.com/ooyala/retries
|
96
101
|
licenses: []
|
102
|
+
metadata: {}
|
97
103
|
post_install_message:
|
98
104
|
rdoc_options: []
|
99
105
|
require_paths:
|
100
106
|
- lib
|
101
107
|
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
-
none: false
|
103
108
|
requirements:
|
104
|
-
- -
|
109
|
+
- - '>='
|
105
110
|
- !ruby/object:Gem::Version
|
106
111
|
version: '0'
|
107
112
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
|
-
none: false
|
109
113
|
requirements:
|
110
|
-
- -
|
114
|
+
- - '>='
|
111
115
|
- !ruby/object:Gem::Version
|
112
116
|
version: '0'
|
113
117
|
requirements: []
|
114
118
|
rubyforge_project:
|
115
|
-
rubygems_version:
|
119
|
+
rubygems_version: 2.0.0
|
116
120
|
signing_key:
|
117
|
-
specification_version:
|
121
|
+
specification_version: 4
|
118
122
|
summary: Retries is a gem for retrying blocks with randomized exponential backoff.
|
119
123
|
test_files:
|
120
124
|
- test/retries_test.rb
|