retriable 3.0.2 → 3.1.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
- data/.gitignore +1 -0
- data/.rubocop.yml +4 -1
- data/.travis.yml +1 -1
- data/CHANGELOG.md +4 -0
- data/README.md +47 -0
- data/lib/retriable.rb +10 -2
- data/lib/retriable/config.rb +2 -0
- data/lib/retriable/core_ext/kernel.rb +4 -0
- data/lib/retriable/version.rb +1 -1
- data/spec/config_spec.rb +4 -0
- data/spec/retriable_spec.rb +55 -0
- 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: 9be10833c09da3a93748eaaae5d13577ee8c520a
|
4
|
+
data.tar.gz: a370e7ea1a328865b3235f316e07bacdc19b6bb1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd0ff1af0d8f50320fa8ff29ed4e53b56fbb33d62638a00206d2e9a816ae11082638b10ae6642f7bf98895f3f48b87e886bbe3dc1997b19863825f0c330ed759
|
7
|
+
data.tar.gz: aec007409a818cb5758c3e853cb6bd684d4676deee14c089f4b10f7fd3284554f71dd5d8079345622b1b99e4f23bf3a874f1c2371916e5e9b8fce13d35009318
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -6,7 +6,7 @@ Style/Documentation:
|
|
6
6
|
|
7
7
|
Style/TrailingCommaInArguments:
|
8
8
|
EnforcedStyleForMultiline: comma
|
9
|
-
|
9
|
+
|
10
10
|
Style/TrailingCommaInLiteral:
|
11
11
|
EnforcedStyleForMultiline: comma
|
12
12
|
|
@@ -19,6 +19,9 @@ Style/IndentArray:
|
|
19
19
|
Style/IndentHash:
|
20
20
|
Enabled: false
|
21
21
|
|
22
|
+
Style/NegatedIf:
|
23
|
+
Enabled: false
|
24
|
+
|
22
25
|
Metrics/ClassLength:
|
23
26
|
Enabled: false
|
24
27
|
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -223,6 +223,49 @@ ensure
|
|
223
223
|
end
|
224
224
|
```
|
225
225
|
|
226
|
+
## Contexts
|
227
|
+
|
228
|
+
Contexts allow you to coordinate sets of Retriable options across an application. Each context is basically an argument hash for `Retriable.retriable` that is stored in the `Retriable.config` as a simple `Hash` and is accessible by name. For example:
|
229
|
+
|
230
|
+
```ruby
|
231
|
+
Retriable.configure do |c|
|
232
|
+
c.contexts[:aws] = {
|
233
|
+
tries: 3,
|
234
|
+
base_interval: 5,
|
235
|
+
on_retry: Proc.new { puts 'Curse you, AWS!' }
|
236
|
+
}
|
237
|
+
c.contexts[:mysql] = {
|
238
|
+
tries: 10,
|
239
|
+
multiplier: 2.5,
|
240
|
+
on: Mysql::DeadlockException
|
241
|
+
}
|
242
|
+
end
|
243
|
+
```
|
244
|
+
|
245
|
+
This will create two contexts, `aws` and `mysql`, which allow you to reuse different backoff strategies across your application without continually passing those strategy options to the `retriable` method.
|
246
|
+
|
247
|
+
These are used simply by calling `Retriable.with_context`:
|
248
|
+
|
249
|
+
```ruby
|
250
|
+
# Will retry all exceptions
|
251
|
+
Retriable.with_context(:aws) do
|
252
|
+
# aws_call
|
253
|
+
end
|
254
|
+
|
255
|
+
# Will retry Mysql::DeadlockException
|
256
|
+
Retriable.with_context(:mysql) do
|
257
|
+
# write_to_table
|
258
|
+
end
|
259
|
+
```
|
260
|
+
|
261
|
+
You can even temporarily override individual options for a configured context:
|
262
|
+
|
263
|
+
```ruby
|
264
|
+
Retriable.with_context(:mysql, tries: 30) do
|
265
|
+
# write_to_table
|
266
|
+
end
|
267
|
+
```
|
268
|
+
|
226
269
|
## Kernel Extension
|
227
270
|
|
228
271
|
If you want to call `Retriable.retriable` without the `Retriable` module prefix and you don't mind extending `Kernel`,
|
@@ -246,6 +289,10 @@ and then you can call `#retriable` in any context like this:
|
|
246
289
|
retriable do
|
247
290
|
# code here...
|
248
291
|
end
|
292
|
+
|
293
|
+
retriable_with_context(:api) do
|
294
|
+
# code here...
|
295
|
+
end
|
249
296
|
```
|
250
297
|
|
251
298
|
## Proxy Wrapper Object
|
data/lib/retriable.rb
CHANGED
@@ -6,7 +6,7 @@ require_relative "retriable/version"
|
|
6
6
|
module Retriable
|
7
7
|
module_function
|
8
8
|
|
9
|
-
def
|
9
|
+
def configure
|
10
10
|
yield(config)
|
11
11
|
end
|
12
12
|
|
@@ -14,6 +14,14 @@ module Retriable
|
|
14
14
|
@config ||= Config.new
|
15
15
|
end
|
16
16
|
|
17
|
+
def with_context(context_key, options = {}, &block)
|
18
|
+
if !config.contexts.key?(context_key)
|
19
|
+
raise ArgumentError, "#{context_key} not found in Retriable.config.contexts. Here the available contexts: #{config.contexts.keys}"
|
20
|
+
end
|
21
|
+
|
22
|
+
retriable(config.contexts[context_key].merge(options), &block) if block
|
23
|
+
end
|
24
|
+
|
17
25
|
def retriable(opts = {})
|
18
26
|
local_config = opts.empty? ? config : Config.new(config.to_h.merge(opts))
|
19
27
|
|
@@ -40,7 +48,7 @@ module Retriable
|
|
40
48
|
base_interval: base_interval,
|
41
49
|
multiplier: multiplier,
|
42
50
|
max_interval: max_interval,
|
43
|
-
rand_factor: rand_factor
|
51
|
+
rand_factor: rand_factor
|
44
52
|
).intervals
|
45
53
|
end
|
46
54
|
|
data/lib/retriable/config.rb
CHANGED
@@ -9,6 +9,7 @@ module Retriable
|
|
9
9
|
:timeout,
|
10
10
|
:on,
|
11
11
|
:on_retry,
|
12
|
+
:contexts,
|
12
13
|
].freeze
|
13
14
|
|
14
15
|
attr_accessor(*ATTRIBUTES)
|
@@ -27,6 +28,7 @@ module Retriable
|
|
27
28
|
@timeout = nil
|
28
29
|
@on = [StandardError]
|
29
30
|
@on_retry = nil
|
31
|
+
@contexts = {}
|
30
32
|
|
31
33
|
opts.each do |k, v|
|
32
34
|
raise ArgumentError, "#{k} is not a valid option" if !ATTRIBUTES.include?(k)
|
data/lib/retriable/version.rb
CHANGED
data/spec/config_spec.rb
CHANGED
@@ -45,6 +45,10 @@ describe Retriable::Config do
|
|
45
45
|
expect(subject.new.on_retry).must_be_nil
|
46
46
|
end
|
47
47
|
|
48
|
+
it "contexts defaults to {}" do
|
49
|
+
expect(subject.new.contexts).must_equal Hash.new
|
50
|
+
end
|
51
|
+
|
48
52
|
it "raises errors on invalid configuration" do
|
49
53
|
assert_raises ArgumentError do
|
50
54
|
subject.new(does_not_exist: 123)
|
data/spec/retriable_spec.rb
CHANGED
@@ -376,4 +376,59 @@ describe Retriable do
|
|
376
376
|
Retriable.retriable(does_not_exist: 123)
|
377
377
|
end
|
378
378
|
end
|
379
|
+
|
380
|
+
describe "#with_context" do
|
381
|
+
before do
|
382
|
+
Retriable.configure do |c|
|
383
|
+
c.sleep_disabled = true
|
384
|
+
c.contexts[:sql] = { tries: 1 }
|
385
|
+
c.contexts[:api] = { tries: 3 }
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
it "sql context stops at first try if the block does not raise an exception" do
|
390
|
+
tries = 0
|
391
|
+
subject.with_context(:sql) do
|
392
|
+
tries += 1
|
393
|
+
end
|
394
|
+
|
395
|
+
expect(tries).must_equal 1
|
396
|
+
end
|
397
|
+
|
398
|
+
it "with_context respects the context options" do
|
399
|
+
tries = 0
|
400
|
+
|
401
|
+
expect do
|
402
|
+
subject.with_context(:api) do
|
403
|
+
tries += 1
|
404
|
+
raise StandardError.new, "StandardError occurred"
|
405
|
+
end
|
406
|
+
end.must_raise StandardError
|
407
|
+
|
408
|
+
expect(tries).must_equal 3
|
409
|
+
end
|
410
|
+
|
411
|
+
it "with_context allows override options" do
|
412
|
+
tries = 0
|
413
|
+
|
414
|
+
expect do
|
415
|
+
subject.with_context(:sql, tries: 5) do
|
416
|
+
tries += 1
|
417
|
+
raise StandardError.new, "StandardError occurred"
|
418
|
+
end
|
419
|
+
end.must_raise StandardError
|
420
|
+
|
421
|
+
expect(tries).must_equal 5
|
422
|
+
end
|
423
|
+
|
424
|
+
it "raises an ArgumentError when the context isn't found" do
|
425
|
+
tries = 0
|
426
|
+
|
427
|
+
expect do
|
428
|
+
subject.with_context(:wtf) do
|
429
|
+
tries += 1
|
430
|
+
end
|
431
|
+
end.must_raise ArgumentError
|
432
|
+
end
|
433
|
+
end
|
379
434
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: retriable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jack Chu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-07-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|