retriable 3.1.1 → 3.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.hound.yml +2 -0
- data/.rspec +2 -0
- data/.rubocop.yml +4 -7
- data/.travis.yml +10 -9
- data/CHANGELOG.md +6 -0
- data/Gemfile +1 -3
- data/README.md +135 -58
- data/lib/retriable.rb +2 -2
- data/lib/retriable/config.rb +1 -1
- data/lib/retriable/exponential_backoff.rb +0 -1
- data/lib/retriable/version.rb +1 -1
- data/retriable.gemspec +3 -7
- data/spec/config_spec.rb +36 -40
- data/spec/exponential_backoff_spec.rb +22 -45
- data/spec/retriable_spec.rb +174 -343
- data/spec/spec_helper.rb +7 -3
- data/spec/support/exceptions.rb +3 -0
- metadata +12 -52
- data/Guardfile +0 -8
- data/Rakefile +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b43ddaf802607e93a68f1f2862c4a951b10f98ff3447f70da26ca72582f5c2ec
|
4
|
+
data.tar.gz: 6893753a86f08975dd6781ce504ef5e373c3ce06ccc56e1fabbb46a701893bfb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 67c9f7740db524df4f4b5301c9c66fbecfc70a98413d4e2dc830f19ecc8365d507373f481a678e53c4ca23063069319d2198bac4f89e6a9641b7c6e0487928f8
|
7
|
+
data.tar.gz: 76f62f0a03ac6e7c43c5fd6e6eeaaa3223edae83e55414bff6ec24464ab1991e6c405e569a7c17cfe0b3904bcec52867e69d9743440e14fb0a7d56ab7ff080fd
|
data/.hound.yml
ADDED
data/.rspec
ADDED
data/.rubocop.yml
CHANGED
@@ -7,16 +7,13 @@ Style/Documentation:
|
|
7
7
|
Style/TrailingCommaInArguments:
|
8
8
|
EnforcedStyleForMultiline: comma
|
9
9
|
|
10
|
-
|
11
|
-
EnforcedStyleForMultiline: comma
|
12
|
-
|
13
|
-
Style/InheritException:
|
10
|
+
Lint/InheritException:
|
14
11
|
Enabled: false
|
15
12
|
|
16
|
-
|
13
|
+
Layout/IndentArray:
|
17
14
|
Enabled: false
|
18
15
|
|
19
|
-
|
16
|
+
Layout/IndentHash:
|
20
17
|
Enabled: false
|
21
18
|
|
22
19
|
Style/NegatedIf:
|
@@ -29,7 +26,7 @@ Metrics/ModuleLength:
|
|
29
26
|
Enabled: false
|
30
27
|
|
31
28
|
Metrics/LineLength:
|
32
|
-
|
29
|
+
Max: 120
|
33
30
|
|
34
31
|
Metrics/MethodLength:
|
35
32
|
Enabled: false
|
data/.travis.yml
CHANGED
@@ -1,24 +1,25 @@
|
|
1
1
|
# Send builds to container-based infrastructure
|
2
2
|
# http://docs.travis-ci.com/user/workers/container-based-infrastructure/
|
3
|
+
dist: trusty
|
3
4
|
sudo: false
|
4
5
|
language: ruby
|
5
6
|
rvm:
|
6
7
|
- 2.0.0
|
7
8
|
- 2.1.10
|
8
|
-
- 2.2.
|
9
|
-
- 2.3.
|
10
|
-
- 2.4.
|
11
|
-
-
|
12
|
-
- jruby-9.0.5.0
|
13
|
-
- jruby-9.1.12.0
|
9
|
+
- 2.2.10
|
10
|
+
- 2.3.7
|
11
|
+
- 2.4.4
|
12
|
+
- 2.5.1
|
14
13
|
- ruby-head
|
14
|
+
- jruby-9.2.0.0
|
15
15
|
- jruby-head
|
16
|
+
- rbx-3.99
|
17
|
+
script:
|
18
|
+
- bundle exec rspec
|
16
19
|
|
17
20
|
matrix:
|
18
21
|
allow_failures:
|
19
|
-
- rvm: rbx
|
20
|
-
- rvm: ruby-head
|
21
|
-
- rvm: jruby-head
|
22
|
+
- rvm: rbx-3.99
|
22
23
|
|
23
24
|
before_install:
|
24
25
|
- gem update --system
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
source "https://rubygems.org"
|
2
2
|
|
3
|
-
# Specify your gem's dependencies in retriable.gemspec
|
4
3
|
gemspec
|
5
4
|
|
6
5
|
group :test do
|
7
|
-
# gem "ruby_gntp"
|
8
6
|
gem "codeclimate-test-reporter", require: false
|
9
|
-
gem "
|
7
|
+
gem "rspec"
|
10
8
|
gem "simplecov", require: false
|
11
9
|
end
|
12
10
|
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
[![Code Climate](https://codeclimate.com/github/kamui/retriable/badges/gpa.svg)](https://codeclimate.com/github/kamui/retriable)
|
5
5
|
[![Test Coverage](https://codeclimate.com/github/kamui/retriable/badges/coverage.svg)](https://codeclimate.com/github/kamui/retriable)
|
6
6
|
|
7
|
-
Retriable is a simple DSL to retry failed code blocks with randomized [exponential backoff](http://en.wikipedia.org/wiki/Exponential_backoff) time intervals. This is especially useful when interacting external
|
7
|
+
Retriable is a simple DSL to retry failed code blocks with randomized [exponential backoff](http://en.wikipedia.org/wiki/Exponential_backoff) time intervals. This is especially useful when interacting external APIs, remote services, or file system calls.
|
8
8
|
|
9
9
|
## Requirements
|
10
10
|
|
@@ -16,7 +16,7 @@ If you need ruby 1.8.x to 1.9.2 support, use the [1.x branch](https://github.com
|
|
16
16
|
|
17
17
|
## Installation
|
18
18
|
|
19
|
-
|
19
|
+
Via command line:
|
20
20
|
|
21
21
|
```ruby
|
22
22
|
gem install retriable
|
@@ -35,21 +35,7 @@ gem 'retriable', '~> 3.1'
|
|
35
35
|
```
|
36
36
|
|
37
37
|
## Usage
|
38
|
-
|
39
|
-
Code in a `Retriable.retriable` block will be retried if an exception is raised. By default, Retriable will rescue any exception inherited from `StandardError`, make 3 tries (including the initial attempt) before raising the last exception, and also use randomized exponential backoff to calculate each succeeding try interval. The default interval table with 10 tries looks like this (in seconds):
|
40
|
-
|
41
|
-
| retry# | retry interval | randomized interval |
|
42
|
-
| -------- | -------------- | ------------------------------- |
|
43
|
-
| 1 | 0.5 | [0.25, 0.75] |
|
44
|
-
| 2 | 0.75 | [0.375, 1.125] |
|
45
|
-
| 3 | 1.125 | [0.5625, 1.6875] |
|
46
|
-
| 4 | 1.6875 | [0.84375, 2.53125] |
|
47
|
-
| 5 | 2.53125 | [1.265625, 3.796875] |
|
48
|
-
| 6 | 3.796875 | [1.8984375, 5.6953125] |
|
49
|
-
| 7 | 5.6953125 | [2.84765625, 8.54296875] |
|
50
|
-
| 8 | 8.54296875 | [4.271484375, 12.814453125] |
|
51
|
-
| 9 | 12.814453125 | [6.4072265625, 19.2216796875] |
|
52
|
-
| 10 | 19.2216796875 | stop |
|
38
|
+
Code in a `Retriable.retriable` block will be retried if an exception is raised.
|
53
39
|
|
54
40
|
```ruby
|
55
41
|
require 'retriable'
|
@@ -64,35 +50,57 @@ class Api
|
|
64
50
|
end
|
65
51
|
```
|
66
52
|
|
67
|
-
###
|
68
|
-
|
69
|
-
|
53
|
+
### Defaults
|
54
|
+
By default, `Retriable` will:
|
55
|
+
* rescue any exception inherited from `StandardError`
|
56
|
+
* make 3 tries (including the initial attempt) before raising the last exception
|
57
|
+
* use randomized exponential backoff to calculate each succeeding try interval.
|
70
58
|
|
71
|
-
|
59
|
+
The default interval table with 10 tries looks like this (in seconds, rounded to the nearest millisecond):
|
72
60
|
|
73
|
-
|
61
|
+
| Retry # | Min | Average | Max |
|
62
|
+
| -------- | -------- | -------- | -------- |
|
63
|
+
| 1 | `0.25` | `0.5` | `0.75` |
|
64
|
+
| 2 | `0.375` | `0.75` | `1.125` |
|
65
|
+
| 3 | `0.563` | `1.125` | `1.688` |
|
66
|
+
| 4 | `0.844` | `1.688` | `2.531` |
|
67
|
+
| 5 | `1.266` | `2.531` | `3.797` |
|
68
|
+
| 6 | `1.898` | `3.797` | `5.695` |
|
69
|
+
| 7 | `2.848` | `5.695` | `8.543` |
|
70
|
+
| 8 | `4.271` | `8.543` | `12.814` |
|
71
|
+
| 9 | `6.407` | `12.814` | `19.222` |
|
72
|
+
| 10 | **stop** | **stop** | **stop** |
|
74
73
|
|
75
|
-
`max_interval` (default: 60) - The maximum interval in seconds that any try can reach.
|
76
74
|
|
77
|
-
|
78
|
-
|
79
|
-
```
|
80
|
-
randomized_interval = retry_interval * (random value in range [1 - randomization_factor, 1 + randomization_factor])
|
81
|
-
```
|
82
|
-
|
83
|
-
`multiplier` (default: 1.5) - Each successive interval grows by this factor. A multipler of 1.5 means the next interval will be 1.5x the current interval.
|
75
|
+
### Options
|
84
76
|
|
85
|
-
|
77
|
+
Here are the available options, in some vague order of relevance to most common use patterns:
|
86
78
|
|
87
|
-
|
79
|
+
| Option | Default | Definition |
|
80
|
+
| ------ | ------- | ---------- |
|
81
|
+
| **`tries`** | `3` | Number of attempts to make at running your code block (includes initial attempt). |
|
82
|
+
| **`on`** | `[StandardError]` | Type of exceptions to retry. [Read more](#configuring-which-options-to-retry-with-on). |
|
83
|
+
| **`on_retry`** | `nil` | `Proc` to call after each try is rescued. [Read more](#callbacks). |
|
84
|
+
| **`base_interval`** | `0.5` | The initial interval in seconds between tries. |
|
85
|
+
| **`max_elapsed_time`** | `900` (15 min) | The maximum amount of total time in seconds that code is allowed to keep being retried. |
|
86
|
+
| **`max_interval`** | `60` | The maximum interval in seconds that any individual retry can reach. |
|
87
|
+
| **`multiplier`** | `1.5` | Each successive interval grows by this factor. A multipler of 1.5 means the next interval will be 1.5x the current interval. |
|
88
|
+
| **`timeout`** | `nil` | Number of seconds to allow the code block to run before raising a `Timeout::Error` inside each try. `nil` means the code block can run forever without raising error. (You may want to read up on [the dangers of using Ruby `Timeout`](https://jvns.ca/blog/2015/11/27/why-rubys-timeout-is-dangerous-and-thread-dot-raise-is-terrifying/) before using this feature.) |
|
89
|
+
| **`rand_factor`** | `0.25` | The percentage to randomize the next retry interval time. The next interval calculation is `randomized_interval = retry_interval * (random value in range [1 - randomization_factor, 1 + randomization_factor])` |
|
90
|
+
| **`intervals`** | `nil` | Skip generated intervals and provide your own array of intervals in seconds. [Read more](#custom-interval-array). |
|
88
91
|
|
89
|
-
|
92
|
+
#### Configuring Which Options to Retry With :on
|
93
|
+
**`:on`** Can take the form:
|
90
94
|
|
91
|
-
|
95
|
+
- An `Exception` class (retry every exception of this type, including subclasses)
|
96
|
+
- An `Array` of `Exception` classes (retry any exception of one of these types, including subclasses)
|
97
|
+
- A `Hash` where the keys are `Exception` classes and the values are one of:
|
98
|
+
- `nil` (retry every exception of the key's type, including subclasses)
|
99
|
+
- A single `Regexp` pattern (retries exceptions ONLY if their `message` matches the pattern)
|
100
|
+
- An array of patterns (retries exceptions ONLY if their `message` matches at least one of the patterns)
|
92
101
|
|
93
|
-
`on_retry` - (default: nil) - Proc to call after each try is rescued.
|
94
102
|
|
95
|
-
###
|
103
|
+
### Configuration
|
96
104
|
|
97
105
|
You can change the global defaults with a `#configure` block:
|
98
106
|
|
@@ -103,12 +111,12 @@ Retriable.configure do |c|
|
|
103
111
|
end
|
104
112
|
```
|
105
113
|
|
106
|
-
###
|
114
|
+
### Example Usage
|
107
115
|
|
108
|
-
|
116
|
+
This example will only retry on a `Timeout::Error`, retry 3 times and sleep for a full second before each try.
|
109
117
|
|
110
118
|
```ruby
|
111
|
-
Retriable.retriable
|
119
|
+
Retriable.retriable(on: Timeout::Error, tries: 3, base_interval: 1) do
|
112
120
|
# code here...
|
113
121
|
end
|
114
122
|
```
|
@@ -116,27 +124,27 @@ end
|
|
116
124
|
You can also specify multiple errors to retry on by passing an array of exceptions.
|
117
125
|
|
118
126
|
```ruby
|
119
|
-
Retriable.retriable
|
127
|
+
Retriable.retriable(on: [Timeout::Error, Errno::ECONNRESET]) do
|
120
128
|
# code here...
|
121
129
|
end
|
122
130
|
```
|
123
131
|
|
124
|
-
You can also
|
132
|
+
You can also use a hash to specify that you only want to retry exceptions with certain messages (see [the documentation above](#configuring-which-options-to-retry-with-on)). This example will retry all `ActiveRecord::RecordNotUnique` exceptions, `ActiveRecord::RecordInvalid` exceptions where the message matches either `/Parent must exist/` or `/Username has already been taken/`, or `Mysql2::Error` exceptions where the message matches `/Duplicate entry/`.
|
125
133
|
|
126
134
|
```ruby
|
127
|
-
Retriable.retriable
|
135
|
+
Retriable.retriable(on: {
|
128
136
|
ActiveRecord::RecordNotUnique => nil,
|
129
|
-
ActiveRecord::RecordInvalid => [/
|
137
|
+
ActiveRecord::RecordInvalid => [/Parent must exist/, /Username has already been taken/],
|
130
138
|
Mysql2::Error => /Duplicate entry/
|
131
|
-
} do
|
139
|
+
}) do
|
132
140
|
# code here...
|
133
141
|
end
|
134
142
|
```
|
135
143
|
|
136
|
-
You can also specify a timeout if you want the code block to only try for X amount of seconds. This timeout is per try.
|
144
|
+
You can also specify a timeout if you want the code block to only try for X amount of seconds. This timeout is per try. (You may want to read up on [the dangers of using Ruby `Timeout`](https://jvns.ca/blog/2015/11/27/why-rubys-timeout-is-dangerous-and-thread-dot-raise-is-terrifying/) before using this feature.)
|
137
145
|
|
138
146
|
```ruby
|
139
|
-
Retriable.retriable
|
147
|
+
Retriable.retriable(timeout: 60) do
|
140
148
|
# code here...
|
141
149
|
end
|
142
150
|
```
|
@@ -144,7 +152,7 @@ end
|
|
144
152
|
If you need millisecond units of time for the sleep or the timeout:
|
145
153
|
|
146
154
|
```ruby
|
147
|
-
Retriable.retriable
|
155
|
+
Retriable.retriable(base_interval: (200 / 1000.0), timeout: (500 / 1000.0)) do
|
148
156
|
# code here...
|
149
157
|
end
|
150
158
|
```
|
@@ -154,39 +162,39 @@ end
|
|
154
162
|
You can also bypass the built-in interval generation and provide your own array of intervals. Supplying your own intervals overrides the `tries`, `base_interval`, `max_interval`, `rand_factor`, and `multiplier` parameters.
|
155
163
|
|
156
164
|
```ruby
|
157
|
-
Retriable.retriable
|
165
|
+
Retriable.retriable(intervals: [0.5, 1.0, 2.0, 2.5]) do
|
158
166
|
# code here...
|
159
167
|
end
|
160
168
|
```
|
161
169
|
|
162
|
-
This example makes 5 total attempts
|
170
|
+
This example makes 5 total attempts. If the first attempt fails, the 2nd attempt occurs 0.5 seconds later.
|
163
171
|
|
164
172
|
### Turn off Exponential Backoff
|
165
173
|
|
166
|
-
Exponential backoff is enabled by default
|
174
|
+
Exponential backoff is enabled by default. If you want to simply retry code every second, 5 times maximum, you can do this:
|
167
175
|
|
168
176
|
```ruby
|
169
|
-
Retriable.retriable
|
177
|
+
Retriable.retriable(tries: 5, base_interval: 1.0, multiplier: 1.0, rand_factor: 0.0) do
|
170
178
|
# code here...
|
171
179
|
end
|
172
180
|
```
|
173
181
|
|
174
|
-
This works by starting at a 1 second
|
182
|
+
This works by starting at a 1 second `base_interval`. Setting the `multipler` to 1.0 means each subsequent try will increase 1x, which is still `1.0` seconds, and then a `rand_factor` of 0.0 means that there's no randomization of that interval. (By default, it would randomize 0.25 seconds, which would mean normally the intervals would randomize between 0.75 and 1.25 seconds, but in this case `rand_factor` is basically being disabled.)
|
175
183
|
|
176
184
|
Another way to accomplish this would be to create an array with a fixed interval. In this example, `Array.new(5, 1)` creates an array with 5 elements, all with the value 1. The code block will retry up to 5 times, and wait 1 second between each attempt.
|
177
185
|
|
178
186
|
```ruby
|
179
187
|
# Array.new(5, 1) # => [1, 1, 1, 1, 1]
|
180
188
|
|
181
|
-
Retriable.retriable
|
189
|
+
Retriable.retriable(intervals: Array.new(5, 1)) do
|
182
190
|
# code here...
|
183
191
|
end
|
184
192
|
```
|
185
193
|
|
186
|
-
If you don't want exponential backoff
|
194
|
+
If you don't want exponential backoff but you still want some randomization between intervals, this code will run every 1 seconds with a randomization factor of 0.2, which means each interval will be a random value between 0.8 and 1.2 (1 second +/- 0.2):
|
187
195
|
|
188
196
|
```ruby
|
189
|
-
Retriable.retriable
|
197
|
+
Retriable.retriable(base_interval: 1.0, multiplier: 1.0, rand_factor: 0.2) do
|
190
198
|
# code here...
|
191
199
|
end
|
192
200
|
```
|
@@ -200,14 +208,14 @@ do_this_on_each_retry = Proc.new do |exception, try, elapsed_time, next_interval
|
|
200
208
|
log "#{exception.class}: '#{exception.message}' - #{try} tries in #{elapsed_time} seconds and #{next_interval} seconds until the next try."
|
201
209
|
end
|
202
210
|
|
203
|
-
Retriable.retriable
|
211
|
+
Retriable.retriable(on_retry: do_this_on_each_retry) do
|
204
212
|
# code here...
|
205
213
|
end
|
206
214
|
```
|
207
215
|
|
208
216
|
### Ensure/Else
|
209
217
|
|
210
|
-
What if I want to execute a code block at the end, whether or not an exception was rescued ([ensure](http://ruby-doc.org/docs/keywords/1.9/Object.html#method-i-ensure))? Or
|
218
|
+
What if I want to execute a code block at the end, whether or not an exception was rescued ([ensure](http://ruby-doc.org/docs/keywords/1.9/Object.html#method-i-ensure))? Or what if I want to execute a code block if no exception is raised ([else](http://ruby-doc.org/docs/keywords/1.9/Object.html#method-i-else))? Instead of providing more callbacks, I recommend you just wrap retriable in a begin/retry/else/ensure block:
|
211
219
|
|
212
220
|
```ruby
|
213
221
|
begin
|
@@ -262,7 +270,7 @@ You can even temporarily override individual options for a configured context:
|
|
262
270
|
|
263
271
|
```ruby
|
264
272
|
Retriable.with_context(:mysql, tries: 30) do
|
265
|
-
# write_to_table
|
273
|
+
# write_to_table with :mysql context, except with 30 tries instead of 10
|
266
274
|
end
|
267
275
|
```
|
268
276
|
|
@@ -295,6 +303,69 @@ retriable_with_context(:api) do
|
|
295
303
|
end
|
296
304
|
```
|
297
305
|
|
306
|
+
## Short Circuiting Retriable While Testing Your App
|
307
|
+
|
308
|
+
When you are running tests for your app it often takes a long time to retry blocks that fail. This is because Retriable will default to 3 tries with exponential backoff. Ideally your tests will run as quickly as possible.
|
309
|
+
|
310
|
+
You can disable retrying by setting `tries` to 1 in the test environment. If you want to test that the code is retrying an error, you want to [turn off exponential backoff](#turn-off-exponential-backoff).
|
311
|
+
|
312
|
+
Under Rails, you could change your initializer to have different options in test, as follows:
|
313
|
+
|
314
|
+
```ruby
|
315
|
+
# config/initializers/retriable.rb
|
316
|
+
Retriable.configure do |c|
|
317
|
+
# ... default configuration
|
318
|
+
|
319
|
+
if Rails.env.test?
|
320
|
+
c.tries = 1
|
321
|
+
end
|
322
|
+
end
|
323
|
+
```
|
324
|
+
|
325
|
+
Alternately, if you are using RSpec, you could override the Retriable confguration in your `spec_helper`.
|
326
|
+
|
327
|
+
```ruby
|
328
|
+
# spec/spec_helper.rb
|
329
|
+
Retriable.configure do |c|
|
330
|
+
c.tries = 1
|
331
|
+
end
|
332
|
+
```
|
333
|
+
|
334
|
+
If you have defined contexts for your configuration, you'll need to change values for each context, because those values take precedence over the default configured value.
|
335
|
+
|
336
|
+
For example assuming you have configured a `google_api` context:
|
337
|
+
```ruby
|
338
|
+
# config/initializers/retriable.rb
|
339
|
+
Retriable.configure do |c|
|
340
|
+
c.contexts[:google_api] = {
|
341
|
+
tries: 5,
|
342
|
+
base_interval: 3,
|
343
|
+
on: [
|
344
|
+
Net::ReadTimeout,
|
345
|
+
Signet::AuthorizationError,
|
346
|
+
Errno::ECONNRESET,
|
347
|
+
OpenSSL::SSL::SSLError
|
348
|
+
]
|
349
|
+
}
|
350
|
+
end
|
351
|
+
```
|
352
|
+
|
353
|
+
Then in your test environment, you would need to set each context and the default value:
|
354
|
+
|
355
|
+
```ruby
|
356
|
+
# spec/spec_helper.rb
|
357
|
+
Retriable.configure do |c|
|
358
|
+
c.multiplier = 1.0
|
359
|
+
c.rand_factor = 0.0
|
360
|
+
c.base_interval = 0
|
361
|
+
|
362
|
+
c.contexts.keys.each do |context|
|
363
|
+
c.contexts[context][:tries] = 1
|
364
|
+
c.contexts[context][:base_interval] = 0
|
365
|
+
end
|
366
|
+
end
|
367
|
+
```
|
368
|
+
|
298
369
|
## Proxy Wrapper Object
|
299
370
|
|
300
371
|
[@julik](https://github.com/julik) has created a gem called [retriable_proxy](https://github.com/julik/retriable_proxy) that extends `retriable` with the ability to wrap objects and specify which methods you want to be retriable, like so:
|
@@ -307,3 +378,9 @@ RetriableProxy.for_object(api_endpoint, on: Net::TimeoutError)
|
|
307
378
|
## Credits
|
308
379
|
|
309
380
|
The randomized exponential backoff implementation was inspired by the one used in Google's [google-http-java-client](https://code.google.com/p/google-http-java-client/wiki/ExponentialBackoff) project.
|
381
|
+
|
382
|
+
## Development
|
383
|
+
### Running Specs
|
384
|
+
```bash
|
385
|
+
bundle exec rspec
|
386
|
+
```
|
data/lib/retriable.rb
CHANGED
@@ -37,6 +37,7 @@ module Retriable
|
|
37
37
|
on_retry = local_config.on_retry
|
38
38
|
sleep_disabled = local_config.sleep_disabled
|
39
39
|
|
40
|
+
exception_list = on.is_a?(Hash) ? on.keys : on
|
40
41
|
start_time = Time.now
|
41
42
|
elapsed_time = -> { Time.now - start_time }
|
42
43
|
|
@@ -52,10 +53,9 @@ module Retriable
|
|
52
53
|
).intervals
|
53
54
|
end
|
54
55
|
|
55
|
-
exception_list = on.is_a?(Hash) ? on.keys : on
|
56
|
-
|
57
56
|
tries.times do |index|
|
58
57
|
try = index + 1
|
58
|
+
|
59
59
|
begin
|
60
60
|
return Timeout.timeout(timeout) { return yield(try) } if timeout
|
61
61
|
return yield(try)
|