retries 0.0.3 → 0.0.4
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.
- 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
|