pester 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/pester/version.rb +1 -1
- data/lib/pester.rb +32 -16
- data/spec/pester_spec.rb +22 -9
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c726cd4ef970107604a3cabf1d26ddf04fffbc45
|
4
|
+
data.tar.gz: 3579a4065f03f7791720e9d98d0c6bdc5a3c57f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e6af9161e42c15a613748d81845adfa8d786b4a5309b41163b87c5d42945968e984e66e84a95f9ba141b2a713c1c30f1a2d5c6b8b8648e516fc1cb0931b84d0
|
7
|
+
data.tar.gz: a5719117192311422b5bce432f1b53cef9d98f12ef3b4e1df6b244d237709353ce64af6152c015b75910226b010119abadd890cc23a5f15eeebf34c441b0f450
|
data/lib/pester/version.rb
CHANGED
data/lib/pester.rb
CHANGED
@@ -26,6 +26,10 @@ module Pester
|
|
26
26
|
# Options:
|
27
27
|
# retry_error_classes - A single or array of exceptions to retry on. Thrown exceptions not in this list
|
28
28
|
# (including parent/sub-classes) will be reraised
|
29
|
+
# retry_error_messages - A single or array of exception messages to retry on. If only this options is passed,
|
30
|
+
# any exception with a message containing one of these strings will be retried. If this
|
31
|
+
# option is passed along with retry_error_classes, retry will only happen when both the
|
32
|
+
# class and the message match the exception. Strings and regexes are both permitted.
|
29
33
|
# reraise_error_classes - A single or array of exceptions to always re-raiseon. Thrown exceptions not in
|
30
34
|
# this list (including parent/sub-classes) will be retried
|
31
35
|
# max_attempts - Max number of attempts to retry
|
@@ -33,18 +37,14 @@ module Pester
|
|
33
37
|
# passed to retry_with_backoff will retry first after 2 seconds, then 4, then 6, et al.
|
34
38
|
# on_retry - A Proc to be called on each successive failure, before the next retry
|
35
39
|
# on_max_attempts_exceeded - A Proc to be called when attempt_num >= max_attempts - 1
|
36
|
-
#
|
37
|
-
# logic, non-matches will cause the exception to be reraised
|
40
|
+
# logger - Where to log the output
|
38
41
|
#
|
39
42
|
# Usage:
|
40
|
-
# retry_action do
|
43
|
+
# retry_action(retry_error_classes: [Mysql2::Error]) do
|
41
44
|
# puts 'trying to remove a directory'
|
42
45
|
# FileUtils.rm_r(directory)
|
43
46
|
# end
|
44
|
-
|
45
|
-
# retryable(error_classes: Mysql2::Error, message: /^Lost connection to MySQL server/, max_attempts: 2) do
|
46
|
-
# ActiveRecord::Base.connection.execute("LONG MYSQL STATEMENT")
|
47
|
-
# end
|
47
|
+
|
48
48
|
def self.retry_action(opts = {}, &block)
|
49
49
|
merge_defaults(opts)
|
50
50
|
if opts[:retry_error_classes] && opts[:reraise_error_classes]
|
@@ -53,16 +53,10 @@ module Pester
|
|
53
53
|
|
54
54
|
opts[:max_attempts].times do |attempt_num|
|
55
55
|
begin
|
56
|
-
|
57
|
-
return result
|
56
|
+
return yield(block)
|
58
57
|
rescue => e
|
59
|
-
|
60
|
-
|
61
|
-
message_reraise = opts[:message] && !e.message[opts[:message]]
|
62
|
-
|
63
|
-
if class_reraise || message_reraise || reraise_error
|
64
|
-
match_type = class_reraise ? 'class' : 'message'
|
65
|
-
opts[:logger].warn("Reraising exception from inside retry_action because provided #{match_type} was not matched.")
|
58
|
+
unless should_retry?(e, opts)
|
59
|
+
opts[:logger].warn('Reraising exception from inside retry_action.')
|
66
60
|
raise
|
67
61
|
end
|
68
62
|
|
@@ -72,6 +66,7 @@ module Pester
|
|
72
66
|
opts[:logger].warn("Failure encountered: #{e}, backing off and trying again #{attempts_left} more times. Trace: #{trace}")
|
73
67
|
opts[:on_retry].call(attempt_num, opts[:delay_interval])
|
74
68
|
else
|
69
|
+
# Careful here because you will get back the return value of the on_max_attempts_exceeded proc!
|
75
70
|
return opts[:on_max_attempts_exceeded].call(opts[:logger], opts[:max_attempts], e)
|
76
71
|
end
|
77
72
|
end
|
@@ -80,8 +75,29 @@ module Pester
|
|
80
75
|
|
81
76
|
private
|
82
77
|
|
78
|
+
def self.should_retry?(e, opts = {})
|
79
|
+
retry_error_classes = opts[:retry_error_classes]
|
80
|
+
retry_error_messages = opts[:retry_error_messages]
|
81
|
+
reraise_error_classes = opts[:reraise_error_classes]
|
82
|
+
|
83
|
+
if retry_error_classes
|
84
|
+
if retry_error_messages
|
85
|
+
retry_error_classes.include?(e.class) && retry_error_messages.any? { |m| e.message[m] }
|
86
|
+
else
|
87
|
+
retry_error_classes.include?(e.class)
|
88
|
+
end
|
89
|
+
elsif retry_error_messages
|
90
|
+
retry_error_messages.any? { |m| e.message[m] }
|
91
|
+
elsif reraise_error_classes && reraise_error_classes.include?(e.class)
|
92
|
+
false
|
93
|
+
else
|
94
|
+
true
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
83
98
|
def self.merge_defaults(opts)
|
84
99
|
opts[:retry_error_classes] = opts[:retry_error_classes] ? Array(opts[:retry_error_classes]) : nil
|
100
|
+
opts[:retry_error_messages] = opts[:retry_error_messages] ? Array(opts[:retry_error_messages]) : nil
|
85
101
|
opts[:reraise_error_classes] = opts[:reraise_error_classes] ? Array(opts[:reraise_error_classes]) : nil
|
86
102
|
opts[:max_attempts] ||= 4
|
87
103
|
opts[:delay_interval] ||= 30
|
data/spec/pester_spec.rb
CHANGED
@@ -55,7 +55,6 @@ shared_examples 'raises an error only in the correct cases with a retry class' d
|
|
55
55
|
let(:actual_error_message) { matching_error_message }
|
56
56
|
|
57
57
|
it_has_behavior "doesn't raise an error"
|
58
|
-
|
59
58
|
it_has_behavior 'returns and succeeds'
|
60
59
|
end
|
61
60
|
end
|
@@ -66,7 +65,6 @@ shared_examples 'raises an error only in the correct cases with a reraise class'
|
|
66
65
|
let(:actual_error_message) { non_matching_error_message }
|
67
66
|
|
68
67
|
it_has_behavior "doesn't raise an error"
|
69
|
-
|
70
68
|
it_has_behavior 'returns and succeeds'
|
71
69
|
end
|
72
70
|
|
@@ -88,7 +86,6 @@ describe 'retry_action' do
|
|
88
86
|
let(:options) { { delay_interval: 0, logger: null_logger } }
|
89
87
|
|
90
88
|
it_has_behavior "doesn't raise an error"
|
91
|
-
|
92
89
|
it_has_behavior 'returns and succeeds'
|
93
90
|
end
|
94
91
|
|
@@ -97,7 +94,6 @@ describe 'retry_action' do
|
|
97
94
|
let(:options) { { max_attempts: 3, logger: null_logger } }
|
98
95
|
|
99
96
|
it_has_behavior "doesn't raise an error"
|
100
|
-
|
101
97
|
it_has_behavior 'returns and succeeds'
|
102
98
|
end
|
103
99
|
|
@@ -111,17 +107,34 @@ describe 'retry_action' do
|
|
111
107
|
it_has_behavior 'raises an error'
|
112
108
|
end
|
113
109
|
|
114
|
-
context 'with on_max_attempts_exceeded specified
|
115
|
-
let(:do_nothing_proc) { proc {} }
|
110
|
+
context 'with on_max_attempts_exceeded proc specified' do
|
116
111
|
let(:options) do
|
117
112
|
{
|
118
113
|
max_attempts: max_attempts,
|
119
|
-
on_max_attempts_exceeded:
|
114
|
+
on_max_attempts_exceeded: proc_to_call,
|
120
115
|
logger: null_logger
|
121
116
|
}
|
122
117
|
end
|
123
118
|
|
124
|
-
|
119
|
+
context 'which does not do anything' do
|
120
|
+
let(:proc_to_call) { proc {} }
|
121
|
+
it_has_behavior "doesn't raise an error"
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'which reraises' do
|
125
|
+
let(:proc_to_call) { Behaviors::WarnAndReraise }
|
126
|
+
it_has_behavior 'raises an error'
|
127
|
+
end
|
128
|
+
|
129
|
+
context 'which returns a value' do
|
130
|
+
let(:return_value) { 'return_value' }
|
131
|
+
let(:proc_to_call) { proc { return_value } }
|
132
|
+
it_has_behavior "doesn't raise an error"
|
133
|
+
|
134
|
+
it 'should return the result of the proc' do
|
135
|
+
expect(Pester.retry_action(options) { action }).to eq(return_value)
|
136
|
+
end
|
137
|
+
end
|
125
138
|
end
|
126
139
|
end
|
127
140
|
|
@@ -138,7 +151,7 @@ describe 'retry_action' do
|
|
138
151
|
let(:options) do
|
139
152
|
{
|
140
153
|
retry_error_classes: expected_error_classes,
|
141
|
-
|
154
|
+
retry_error_messages: /^Lost connection to MySQL server/,
|
142
155
|
max_attempts: 10,
|
143
156
|
logger: null_logger
|
144
157
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pester
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marc Bollinger
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|