attempt 0.3.2 → 0.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CHANGES +6 -0
- data/attempt.gemspec +3 -1
- data/certs/djberg96_pub.pem +15 -15
- data/lib/attempt.rb +41 -30
- data/test.rb +10 -0
- data/test/test_attempt.rb +10 -6
- metadata +33 -18
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1ec70ec03f74ac462d0981aae31fd9e896b9aa68
|
4
|
+
data.tar.gz: 00a6fda1a874fe350ba06867f595e84c311cdf92
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48a3c30acad26d4411cf450897defea366d343294e0b43f16f5685900461b323256da6f2c0a390c993da09dac844c1934bb213fbc5f17269154e12449aeed2cd
|
7
|
+
data.tar.gz: fddca1ffba92d22baf4c2d7ff6a4f6b410e33aee00f0045c6780a535fb3af93f62bd333241b27483140d41f25f8c5342d1feebd6ea39c873bcacf8adc94431a8
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/CHANGES
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
== 0.4.0 - 5-Sep-2017
|
2
|
+
* Switched constructor to use keyword arguments.
|
3
|
+
* Replaced Timeout with SafeTimeout and added the safe_timeout dependency.
|
4
|
+
* The :log option now accepts either an IO or Logger object.
|
5
|
+
* Updated cert.
|
6
|
+
|
1
7
|
== 0.3.2 - 4-Apr-2017
|
2
8
|
* Fix metadata key names.
|
3
9
|
|
data/attempt.gemspec
CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = 'attempt'
|
5
|
-
spec.version = '0.
|
5
|
+
spec.version = '0.4.0'
|
6
6
|
spec.author = 'Daniel J. Berger'
|
7
7
|
spec.license = 'Artistic 2.0'
|
8
8
|
spec.email = 'djberg96@gmail.com'
|
@@ -22,6 +22,8 @@ Gem::Specification.new do |spec|
|
|
22
22
|
}
|
23
23
|
|
24
24
|
spec.add_dependency('structured_warnings', '~> 0.3.0')
|
25
|
+
spec.add_dependency('safe_timeout', '~> 0.0.5')
|
26
|
+
|
25
27
|
spec.add_development_dependency('test-unit')
|
26
28
|
|
27
29
|
spec.description = <<-EOF
|
data/certs/djberg96_pub.pem
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
-----BEGIN CERTIFICATE-----
|
2
2
|
MIIDcDCCAligAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MREwDwYDVQQDDAhkamJl
|
3
3
|
cmc5NjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29t
|
4
|
-
|
4
|
+
MB4XDTE3MDkwMzE1MjMxM1oXDTE4MDkwMzE1MjMxM1owPzERMA8GA1UEAwwIZGpi
|
5
5
|
ZXJnOTYxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
6
|
+
bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ8y4kEssxNpAdPhNNw2
|
7
|
+
p4zkERFndPAnmOKDdErczFYYUA9uYpA7/iTjkLlNyRwvsNHpnMXdSF7vy++YIU+F
|
8
|
+
Ux3AGTmspupbdSzqBNUhSEJ9TmpjMer1dMYMR9fRw3r3qQreiO2u/O/tV4VpzrDj
|
9
|
+
28JC0b1PcKtfobxbnk+hporZqTH6ClOxDsRx+trlkr7q7FLZwTZn0ywjAV8WMVTO
|
10
|
+
SMmkzXQ37s2Nnrq6r+dDZI0voBxyQkAUzmdBOQTrvOFAo3tuWcnJNR/RRdFhJ9nK
|
11
|
+
mYMPmEd1z0s+cU0SUEeTvhGv/9LCmbSyZqKezDLYNR4Gb0FOA9D50+4OOi2+3G1o
|
12
|
+
1U0CAwEAAaN3MHUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFJCx
|
13
|
+
ukSSioTiLtwQCdML0IyEZAJ/MB0GA1UdEQQWMBSBEmRqYmVyZzk2QGdtYWlsLmNv
|
14
14
|
bTAdBgNVHRIEFjAUgRJkamJlcmc5NkBnbWFpbC5jb20wDQYJKoZIhvcNAQEFBQAD
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
15
|
+
ggEBAJh/dmRaTpJAUeJ2x9CEyy9gSP6SZjMeAwWgPNdowPDyw0JzlpBIrYiTnCYK
|
16
|
+
2OqxvIi8L38+rHw3KYL0fEyNqP3RbMl6+SljRwiU0JwEqj9e1pqIx99RTLKeI9PM
|
17
|
+
F8LxxmDHreGOaY4R8JBOMxys1wBkF/Iilx4qoT4LBn+DzraAlmYjr6O6itIxGten
|
18
|
+
NFJFS/tFBTTeNW6SJLdDnGd2b7vBBEd/ZpIhuZNxriU6FKWC5FJeBdAiuw6lqHun
|
19
|
+
QLLepVJthIvwmfc8AU5TJGMawtVAUHIWiuQPoBBVVKOkeEhioO0cV8UabKsKMbE8
|
20
|
+
VpiARrgH+4lYiRFJ+gKpIbSEJvk=
|
21
21
|
-----END CERTIFICATE-----
|
data/lib/attempt.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'safe_timeout'
|
2
2
|
require 'structured_warnings'
|
3
3
|
|
4
4
|
# The Attempt class encapsulates methods related to multiple attempts at
|
@@ -6,7 +6,7 @@ require 'structured_warnings'
|
|
6
6
|
class Attempt
|
7
7
|
|
8
8
|
# The version of the attempt library.
|
9
|
-
VERSION = '0.
|
9
|
+
VERSION = '0.4.0'.freeze
|
10
10
|
|
11
11
|
# Warning raised if an attempt fails before the maximum number of tries
|
12
12
|
# has been reached.
|
@@ -38,21 +38,34 @@ class Attempt
|
|
38
38
|
attr_accessor :level
|
39
39
|
|
40
40
|
# :call-seq:
|
41
|
-
# Attempt.new
|
41
|
+
# Attempt.new(**kwargs)
|
42
42
|
#
|
43
|
-
# Creates and returns a new +Attempt+ object.
|
44
|
-
#
|
43
|
+
# Creates and returns a new +Attempt+ object. The supported keyword options
|
44
|
+
# are as follows:
|
45
45
|
#
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
46
|
+
# * tries - The number of attempts to make before giving up. The default is 3.
|
47
|
+
# * interval - The delay in seconds between each attempt. The default is 60.
|
48
|
+
# * log - An IO handle or Logger instance where warnings/errors are logged to. The default is nil.
|
49
|
+
# * increment - The amount to increment the interval between tries. The default is 0.
|
50
|
+
# * level - The level of exception to be caught. The default is everything, i.e. Exception.
|
51
|
+
# * warnings - Boolean value that indicates whether or not errors are treated as warnings
|
52
|
+
# until the maximum number of attempts has been made. The default is true.
|
53
|
+
# * timeout - Boolean value to indicate whether or not to automatically wrap your
|
54
|
+
# proc in a SafeTimeout block. The default is false.
|
55
|
+
#
|
56
|
+
# Example:
|
57
|
+
#
|
58
|
+
# a = Attempt.new(tries: 5, increment: 10, timeout: true)
|
59
|
+
# a.attempt{ http.get("http://something.foo.com") }
|
60
|
+
#
|
61
|
+
def initialize(**options)
|
62
|
+
@tries = options[:tries] || 3 # Reasonable default
|
63
|
+
@interval = options[:interval] || 60 # Reasonable default
|
64
|
+
@log = options[:log] # Should be an IO handle, if provided
|
65
|
+
@increment = options[:increment] || 0 # Should be an integer, if provided
|
66
|
+
@timeout = options[:timeout] || false # Wrap the code in a timeout block if provided
|
67
|
+
@level = options[:level] || Exception # Level of exception to be caught
|
68
|
+
@warnings = options[:warnings] || true # Errors are sent to STDERR as warnings if true
|
56
69
|
end
|
57
70
|
|
58
71
|
# Attempt to perform the operation in the provided block up to +tries+
|
@@ -65,7 +78,7 @@ class Attempt
|
|
65
78
|
count = 1
|
66
79
|
begin
|
67
80
|
if @timeout
|
68
|
-
|
81
|
+
SafeTimeout.timeout(@timeout){ yield }
|
69
82
|
else
|
70
83
|
yield
|
71
84
|
end
|
@@ -75,7 +88,11 @@ class Attempt
|
|
75
88
|
msg = "Error on attempt # #{count}: #{error}; retrying"
|
76
89
|
count += 1
|
77
90
|
warn Warning, msg if @warnings
|
78
|
-
|
91
|
+
|
92
|
+
if @log # Accept an IO or Logger object
|
93
|
+
@log.respond_to?(:puts) ? @log.puts(msg) : @log.warn(msg)
|
94
|
+
end
|
95
|
+
|
79
96
|
@interval += @increment if @increment
|
80
97
|
sleep @interval
|
81
98
|
retry
|
@@ -87,34 +104,28 @@ end
|
|
87
104
|
|
88
105
|
module Kernel
|
89
106
|
# :call-seq:
|
90
|
-
# attempt(tries
|
107
|
+
# attempt(tries: 3, interval: 60, timeout: 10){ # some op }
|
91
108
|
#
|
92
109
|
# Attempt to perform the operation in the provided block up to +tries+
|
93
|
-
# times, sleeping +interval+ between each try.
|
110
|
+
# times, sleeping +interval+ between each try. By default the number
|
94
111
|
# of tries defaults to 3, the interval defaults to 60 seconds, and there
|
95
112
|
# is no timeout specified.
|
96
113
|
#
|
97
114
|
# If +timeout+ is provided then the operation is wrapped in a Timeout
|
98
|
-
# block as well.
|
115
|
+
# block as well. This is handy for those rare occasions when an IO
|
99
116
|
# connection could hang indefinitely, for example.
|
100
117
|
#
|
101
118
|
# If the operation still fails the (last) error is then re-raised.
|
102
119
|
#
|
103
|
-
# This is really just a wrapper for Attempt.new
|
104
|
-
# good enough i.e. you don't care about warnings, increments or logging,
|
105
|
-
# and you want a little added convenience.
|
120
|
+
# This is really just a convenient wrapper for Attempt.new + Attempt#attempt.
|
106
121
|
#
|
107
122
|
# Example:
|
108
123
|
#
|
109
124
|
# # Make 3 attempts to connect to the database, 60 seconds apart.
|
110
125
|
# attempt{ DBI.connect(dsn, user, passwd) }
|
111
126
|
#
|
112
|
-
def attempt(
|
113
|
-
|
114
|
-
|
115
|
-
a.tries = tries
|
116
|
-
a.interval = interval
|
117
|
-
a.timeout = timeout if timeout
|
118
|
-
}.attempt(&block)
|
127
|
+
def attempt(**kwargs, &block)
|
128
|
+
object = Attempt.new(kwargs)
|
129
|
+
object.attempt(&block)
|
119
130
|
end
|
120
131
|
end
|
data/test.rb
ADDED
data/test/test_attempt.rb
CHANGED
@@ -23,7 +23,7 @@ class TC_Attempt < Test::Unit::TestCase
|
|
23
23
|
end
|
24
24
|
|
25
25
|
test "version constant is set to expected value" do
|
26
|
-
assert_equal('0.
|
26
|
+
assert_equal('0.4.0', Attempt::VERSION)
|
27
27
|
end
|
28
28
|
|
29
29
|
test "attempt works as expected without arguments" do
|
@@ -31,24 +31,28 @@ class TC_Attempt < Test::Unit::TestCase
|
|
31
31
|
end
|
32
32
|
|
33
33
|
test "attempt retries the number of times specified" do
|
34
|
-
assert_nothing_raised{ attempt(@tries){ $value += 1; raise if $value < 2 } }
|
34
|
+
assert_nothing_raised{ attempt(tries: @tries){ $value += 1; raise if $value < 2 } }
|
35
35
|
assert_equal(2, $value)
|
36
36
|
end
|
37
37
|
|
38
38
|
test "attempt retries the number of times specified with interval" do
|
39
|
-
assert_nothing_raised{
|
39
|
+
assert_nothing_raised{
|
40
|
+
attempt(tries: @tries, interval: @interval){ $value += 1; raise if $value < 2 }
|
41
|
+
}
|
40
42
|
end
|
41
43
|
|
42
44
|
test "attempt retries the number of times specified with interval and timeout" do
|
43
|
-
assert_nothing_raised{
|
45
|
+
assert_nothing_raised{
|
46
|
+
attempt(tries: @tries, interval: @interval, timeout: @timeout){ $value += 1; raise if $value < 2 }
|
47
|
+
}
|
44
48
|
end
|
45
49
|
|
46
50
|
test "attempt raises a timeout error if timeout value is exceeded" do
|
47
|
-
assert_raises(Timeout::Error){ attempt(1, 1, @timeout){ sleep 5 } }
|
51
|
+
assert_raises(Timeout::Error){ attempt(tries: 1, interval: 1, timeout: @timeout){ sleep 5 } }
|
48
52
|
end
|
49
53
|
|
50
54
|
test "attempt raises exception as expected" do
|
51
|
-
assert_raises(RuntimeError){ attempt(2, 2){ raise } }
|
55
|
+
assert_raises(RuntimeError){ attempt(tries: 2, interval: 2){ raise } }
|
52
56
|
end
|
53
57
|
|
54
58
|
def teardown
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attempt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel J. Berger
|
@@ -12,25 +12,25 @@ cert_chain:
|
|
12
12
|
-----BEGIN CERTIFICATE-----
|
13
13
|
MIIDcDCCAligAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MREwDwYDVQQDDAhkamJl
|
14
14
|
cmc5NjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29t
|
15
|
-
|
15
|
+
MB4XDTE3MDkwMzE1MjMxM1oXDTE4MDkwMzE1MjMxM1owPzERMA8GA1UEAwwIZGpi
|
16
16
|
ZXJnOTYxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
17
|
+
bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ8y4kEssxNpAdPhNNw2
|
18
|
+
p4zkERFndPAnmOKDdErczFYYUA9uYpA7/iTjkLlNyRwvsNHpnMXdSF7vy++YIU+F
|
19
|
+
Ux3AGTmspupbdSzqBNUhSEJ9TmpjMer1dMYMR9fRw3r3qQreiO2u/O/tV4VpzrDj
|
20
|
+
28JC0b1PcKtfobxbnk+hporZqTH6ClOxDsRx+trlkr7q7FLZwTZn0ywjAV8WMVTO
|
21
|
+
SMmkzXQ37s2Nnrq6r+dDZI0voBxyQkAUzmdBOQTrvOFAo3tuWcnJNR/RRdFhJ9nK
|
22
|
+
mYMPmEd1z0s+cU0SUEeTvhGv/9LCmbSyZqKezDLYNR4Gb0FOA9D50+4OOi2+3G1o
|
23
|
+
1U0CAwEAAaN3MHUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFJCx
|
24
|
+
ukSSioTiLtwQCdML0IyEZAJ/MB0GA1UdEQQWMBSBEmRqYmVyZzk2QGdtYWlsLmNv
|
25
25
|
bTAdBgNVHRIEFjAUgRJkamJlcmc5NkBnbWFpbC5jb20wDQYJKoZIhvcNAQEFBQAD
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
26
|
+
ggEBAJh/dmRaTpJAUeJ2x9CEyy9gSP6SZjMeAwWgPNdowPDyw0JzlpBIrYiTnCYK
|
27
|
+
2OqxvIi8L38+rHw3KYL0fEyNqP3RbMl6+SljRwiU0JwEqj9e1pqIx99RTLKeI9PM
|
28
|
+
F8LxxmDHreGOaY4R8JBOMxys1wBkF/Iilx4qoT4LBn+DzraAlmYjr6O6itIxGten
|
29
|
+
NFJFS/tFBTTeNW6SJLdDnGd2b7vBBEd/ZpIhuZNxriU6FKWC5FJeBdAiuw6lqHun
|
30
|
+
QLLepVJthIvwmfc8AU5TJGMawtVAUHIWiuQPoBBVVKOkeEhioO0cV8UabKsKMbE8
|
31
|
+
VpiARrgH+4lYiRFJ+gKpIbSEJvk=
|
32
32
|
-----END CERTIFICATE-----
|
33
|
-
date: 2017-
|
33
|
+
date: 2017-09-05 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: structured_warnings
|
@@ -46,6 +46,20 @@ dependencies:
|
|
46
46
|
- - "~>"
|
47
47
|
- !ruby/object:Gem::Version
|
48
48
|
version: 0.3.0
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: safe_timeout
|
51
|
+
requirement: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 0.0.5
|
56
|
+
type: :runtime
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 0.0.5
|
49
63
|
- !ruby/object:Gem::Dependency
|
50
64
|
name: test-unit
|
51
65
|
requirement: !ruby/object:Gem::Requirement
|
@@ -85,6 +99,7 @@ files:
|
|
85
99
|
- README
|
86
100
|
- test
|
87
101
|
- test/test_attempt.rb
|
102
|
+
- test.rb
|
88
103
|
homepage: https://github.com/djberg96/attempt
|
89
104
|
licenses:
|
90
105
|
- Artistic 2.0
|
@@ -109,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
109
124
|
version: '0'
|
110
125
|
requirements: []
|
111
126
|
rubyforge_project:
|
112
|
-
rubygems_version: 2.6.
|
127
|
+
rubygems_version: 2.6.12
|
113
128
|
signing_key:
|
114
129
|
specification_version: 4
|
115
130
|
summary: A thin wrapper for begin + rescue + sleep + retry
|
metadata.gz.sig
CHANGED
Binary file
|