easy_retry 1.0.7 → 1.0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +7 -7
- data/README.md +81 -34
- data/lib/easy_retry/configuration.rb +2 -1
- data/lib/easy_retry/core.rb +22 -5
- data/lib/easy_retry/version.rb +1 -1
- data/lib/easy_retry.rb +13 -0
- metadata +58 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1dd6fbeba47923f12a6c9ec7fce4f67f7369a612790756b1ba2459492282199f
|
4
|
+
data.tar.gz: aecd43808908c13e591ae1b7a248eebe864d2195959f27a39b87e9142075a548
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 172f6145588b03f8240d809e58e9fe390f093f0f81cadb589fa5d50cbf56c0ab2e076446425fb4cf552790eda81338baf796da8b7879e7b71bb7c84e014500b8
|
7
|
+
data.tar.gz: b150f796f511124b0b05abfbc7fa7a6d4c621703d0b1fe6acbc7e141130b9dd44d5215a5210ad438ed6b419b0cb47a88a0ba59128a697c39852a27aeb6c0de5c
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
easy_retry (1.0.
|
4
|
+
easy_retry (1.0.8)
|
5
5
|
logger (~> 1.5.1)
|
6
6
|
|
7
7
|
GEM
|
@@ -11,11 +11,11 @@ GEM
|
|
11
11
|
coderay (1.1.3)
|
12
12
|
diff-lcs (1.5.0)
|
13
13
|
docile (1.4.0)
|
14
|
-
json (2.6.
|
15
|
-
logger (1.5.
|
14
|
+
json (2.6.3)
|
15
|
+
logger (1.5.2)
|
16
16
|
method_source (1.0.0)
|
17
17
|
parallel (1.22.1)
|
18
|
-
parser (3.1.
|
18
|
+
parser (3.1.3.0)
|
19
19
|
ast (~> 2.4.1)
|
20
20
|
pry (0.14.1)
|
21
21
|
coderay (~> 1.1)
|
@@ -33,11 +33,11 @@ GEM
|
|
33
33
|
rspec-expectations (3.12.0)
|
34
34
|
diff-lcs (>= 1.2.0, < 2.0)
|
35
35
|
rspec-support (~> 3.12.0)
|
36
|
-
rspec-mocks (3.12.
|
36
|
+
rspec-mocks (3.12.1)
|
37
37
|
diff-lcs (>= 1.2.0, < 2.0)
|
38
38
|
rspec-support (~> 3.12.0)
|
39
39
|
rspec-support (3.12.0)
|
40
|
-
rubocop (1.
|
40
|
+
rubocop (1.40.0)
|
41
41
|
json (~> 2.3)
|
42
42
|
parallel (~> 1.10)
|
43
43
|
parser (>= 3.1.2.1)
|
@@ -47,7 +47,7 @@ GEM
|
|
47
47
|
rubocop-ast (>= 1.23.0, < 2.0)
|
48
48
|
ruby-progressbar (~> 1.7)
|
49
49
|
unicode-display_width (>= 1.4.0, < 3.0)
|
50
|
-
rubocop-ast (1.
|
50
|
+
rubocop-ast (1.24.0)
|
51
51
|
parser (>= 3.1.1.0)
|
52
52
|
ruby-progressbar (1.11.0)
|
53
53
|
simplecov (0.21.2)
|
data/README.md
CHANGED
@@ -28,24 +28,24 @@ Or install it yourself as:
|
|
28
28
|
|
29
29
|
If you're not using Bundler, you'll need to require the gem in your code:
|
30
30
|
```rb
|
31
|
-
|
31
|
+
require 'easy_retry'
|
32
32
|
```
|
33
33
|
|
34
34
|
### Basic Example
|
35
35
|
|
36
36
|
```rb
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
4.tries do |try|
|
38
|
+
raise 'Something went wrong' if try < 4
|
39
|
+
puts "Success!"
|
40
|
+
end
|
41
41
|
```
|
42
42
|
|
43
43
|
The code above will produce the following output:
|
44
44
|
|
45
45
|
```
|
46
|
-
|
47
|
-
|
48
|
-
|
46
|
+
RuntimeError: Something went wrong (1/4)
|
47
|
+
RuntimeError: Something went wrong (2/4)
|
48
|
+
RuntimeError: Something went wrong (3/4)
|
49
49
|
Success!
|
50
50
|
```
|
51
51
|
|
@@ -54,29 +54,28 @@ The code above will produce the following output:
|
|
54
54
|
Sometimes you want to only retry your code if a specific exception is raised. You can do this by passing a list of exceptions to the #tries method:
|
55
55
|
|
56
56
|
```rb
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
57
|
+
4.tries(rescue_from: [ZeroDivisionError, ArgumentError]) do |try|
|
58
|
+
raise ZeroDivisionError, 'Whoops' if try < 2
|
59
|
+
raise ActiveRecord::RecordInvalid if try < 4
|
60
|
+
puts "Success!"
|
61
|
+
end
|
62
62
|
```
|
63
63
|
|
64
64
|
The code above will not rescue from the `ActiveRecord::RecordInvalid` error and produce the following output:
|
65
65
|
|
66
66
|
```
|
67
|
-
|
67
|
+
ZeroDivisionError: Whoops (1/4)
|
68
68
|
ActiveRecord::RecordInvalid: Record invalid
|
69
|
-
from (pry):16:in `block in __pry__'
|
70
69
|
```
|
71
70
|
|
72
71
|
Passing an array is not necessary if you need to only rescue from a single error
|
73
72
|
|
74
73
|
```rb
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
74
|
+
4.tries(rescue_from: ZeroDivisionError) do |try|
|
75
|
+
raise ZeroDivisionError if try < 2
|
76
|
+
raise ActiveRecord::RecordInvalid if try < 4
|
77
|
+
puts "Success!"
|
78
|
+
end
|
80
79
|
```
|
81
80
|
|
82
81
|
This will generate the same output.
|
@@ -86,19 +85,54 @@ This will generate the same output.
|
|
86
85
|
EasyRetry gives you back the result of the first time the block you passed successfully runs. This can be useful when you need to use the result of the block for other tasks that you do not necessarily want to place in the block.
|
87
86
|
|
88
87
|
```rb
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
88
|
+
result = 2.tries do |try|
|
89
|
+
raise 'Woops' if try < 2
|
90
|
+
"This is try number #{try}"
|
91
|
+
end
|
93
92
|
|
94
|
-
|
93
|
+
puts result
|
95
94
|
```
|
96
95
|
|
97
96
|
The code above will produce the following output.
|
98
97
|
|
99
98
|
```
|
100
|
-
|
101
|
-
|
99
|
+
RuntimeError: Woops (1/2)
|
100
|
+
=> "This is try number 2"
|
101
|
+
```
|
102
|
+
|
103
|
+
## Custom delay
|
104
|
+
|
105
|
+
EasyRetry allows you to set the delay algorithm you want to use every time you call the `#tries` method. The following predefined options exist: `:none`, `:by_try`, `:default`, `:exponential`.
|
106
|
+
|
107
|
+
__*:none*__
|
108
|
+
|
109
|
+
After a try fails, EasyRetry will not wait and try again immediately.
|
110
|
+
|
111
|
+
__*:by_try*__
|
112
|
+
|
113
|
+
After a try fails, EasyRetry will wait an equal amount of seconds to current try that failed. I.e. 1 second for try one, 2 for try two, 3 for try three, etc.
|
114
|
+
|
115
|
+
__*:default*__
|
116
|
+
|
117
|
+
After a try fails, EasyRetry will wait _n^2_, where _n_ is the current try that failed.
|
118
|
+
|
119
|
+
__*:exponential*__
|
120
|
+
|
121
|
+
After a try fails, EasyRetry will wait _2^n_, where _n_ is the current try that failed.
|
122
|
+
|
123
|
+
### Usage
|
124
|
+
You can use the predefined delay algorithms as follows:
|
125
|
+
```rb
|
126
|
+
3.tries(delay: :none) do
|
127
|
+
raise StandardError
|
128
|
+
end
|
129
|
+
```
|
130
|
+
|
131
|
+
You can also define a custom lambda function if the predefined options are not meeting your needs. You can use it like this:
|
132
|
+
```rb
|
133
|
+
3.tries(delay: ->(current_try) { sleep current_try * 9.81 }) do
|
134
|
+
raise StandardError
|
135
|
+
end
|
102
136
|
```
|
103
137
|
|
104
138
|
## Configuration
|
@@ -106,9 +140,9 @@ The code above will produce the following output.
|
|
106
140
|
You can configure EasyRetry by adding an initializer as follows:
|
107
141
|
|
108
142
|
```rb
|
109
|
-
|
110
|
-
|
111
|
-
|
143
|
+
EasyRetry.configure do |config|
|
144
|
+
# configuration options
|
145
|
+
end
|
112
146
|
```
|
113
147
|
|
114
148
|
### Logger
|
@@ -116,21 +150,34 @@ You can configure EasyRetry by adding an initializer as follows:
|
|
116
150
|
By default, EasyRetry uses [logger](https://rubygems.org/gems/logger) for logging errors. You can add your custom logger in the configuration using the `config.logger` option.
|
117
151
|
|
118
152
|
```rb
|
119
|
-
|
120
|
-
|
153
|
+
# For Example, using Rails.logger
|
154
|
+
config.logger = Rails.logger
|
121
155
|
```
|
122
156
|
|
123
157
|
NB: The logger should follow Rails Logger conventions.
|
124
158
|
|
159
|
+
### Default Delay Algorithm
|
160
|
+
By default the `:default` delay algorithm (_n^2_) is used, what's in a name you could say. You can configure the default delay algorithm through the config as follows:
|
161
|
+
|
162
|
+
```rb
|
163
|
+
config.delay_algorithm = :default # Or :none, :by_try, :exponential
|
164
|
+
```
|
165
|
+
|
166
|
+
Of course, also here you can instead use a custom lambda delay:
|
167
|
+
|
168
|
+
```rb
|
169
|
+
config.delay_algorithm = ->(current_try) { sleep current_try * 9.81 }
|
170
|
+
```
|
171
|
+
|
125
172
|
## Retry delay
|
126
173
|
|
127
174
|
The delay for each retry is based on the iteration count. The delay after each failed attempt is _n^2_, where _n_ is the current iteration that failed. E.g. after the first try, EasyRetry waits 1 second, after the second try it waits 4 seconds, then 9, then 16, then 25, then 36, etc.
|
128
175
|
|
129
176
|
## Development
|
130
177
|
|
131
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `
|
178
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `be rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
132
179
|
|
133
|
-
To install this gem onto your local machine, run `bundle exec rake install`.
|
180
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
134
181
|
|
135
182
|
## Contributing
|
136
183
|
|
data/lib/easy_retry/core.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
# Extend the Numeric class with a #tries method
|
4
4
|
class Numeric
|
5
5
|
# rubocop:disable Metrics/MethodLength
|
6
|
-
def tries(rescue_from: [StandardError])
|
6
|
+
def tries(rescue_from: [StandardError], delay: EasyRetry.delay_algorithm)
|
7
7
|
raise ArgumentError, 'No block given' unless block_given?
|
8
8
|
|
9
9
|
rescue_from = Array(rescue_from)
|
@@ -16,11 +16,9 @@ class Numeric
|
|
16
16
|
|
17
17
|
break
|
18
18
|
rescue *rescue_from => e
|
19
|
-
|
19
|
+
log_failed_try(e, current_try, max_retry)
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
sleep current_try * current_try
|
21
|
+
call_delay(delay, current_try)
|
24
22
|
|
25
23
|
current_try += 1
|
26
24
|
end
|
@@ -30,4 +28,23 @@ class Numeric
|
|
30
28
|
# rubocop:enable Metrics/MethodLength
|
31
29
|
|
32
30
|
alias try tries
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def call_delay(delay, current_try)
|
35
|
+
return delay.call(current_try) if delay.is_a?(Proc)
|
36
|
+
|
37
|
+
EasyRetry.delay_options[delay].call(current_try)
|
38
|
+
end
|
39
|
+
|
40
|
+
def log_failed_try(error, current_try, max_retry)
|
41
|
+
message = error.message == error.class.name ? ' ' : ": #{error.message} "
|
42
|
+
|
43
|
+
if current_try >= max_retry
|
44
|
+
EasyRetry.logger.info "FAILED Permanently after #{max_retry} tries; #{error.class.name}#{message}".strip
|
45
|
+
raise
|
46
|
+
else
|
47
|
+
EasyRetry.logger.info "#{error.class.name}#{message}(Try Number #{current_try}/#{max_retry})"
|
48
|
+
end
|
49
|
+
end
|
33
50
|
end
|
data/lib/easy_retry/version.rb
CHANGED
data/lib/easy_retry.rb
CHANGED
@@ -18,5 +18,18 @@ module EasyRetry
|
|
18
18
|
def logger
|
19
19
|
configuration.logger
|
20
20
|
end
|
21
|
+
|
22
|
+
def delay_algorithm
|
23
|
+
configuration.delay_algorithm
|
24
|
+
end
|
25
|
+
|
26
|
+
def delay_options
|
27
|
+
{
|
28
|
+
none: ->(_try_number) {},
|
29
|
+
by_try: ->(try_number) { sleep try_number },
|
30
|
+
default: ->(try_number) { sleep try_number * try_number },
|
31
|
+
exponential: ->(try_number) { sleep 2**try_number }
|
32
|
+
}
|
33
|
+
end
|
21
34
|
end
|
22
35
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: easy_retry
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robin Goudeketting, Peter Duijnstee
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-12-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logger
|
@@ -24,6 +24,62 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 1.5.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.21'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.21'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
27
83
|
description: Easily retry a block of code a predetermined number of times
|
28
84
|
email:
|
29
85
|
- robin@goudeketting.nl
|