retriable 3.8.0 → 4.0.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/.github/workflows/main.yml +20 -7
- data/.hound.yml +1 -1
- data/.rubocop.yml +4 -1
- data/CHANGELOG.md +18 -0
- data/Gemfile +2 -1
- data/README.md +88 -48
- data/lib/retriable/config.rb +3 -57
- data/lib/retriable/core_ext/kernel.rb +4 -4
- data/lib/retriable/validation.rb +4 -7
- data/lib/retriable/version.rb +1 -1
- data/lib/retriable.rb +36 -24
- data/retriable.gemspec +2 -7
- data/spec/config_spec.rb +17 -97
- data/spec/retriable_spec.rb +287 -93
- data/spec/spec_helper.rb +0 -13
- metadata +6 -52
data/spec/retriable_spec.rb
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "rbconfig"
|
|
4
|
-
require "stringio"
|
|
5
4
|
|
|
6
5
|
describe Retriable do
|
|
7
6
|
let(:time_table_handler) do
|
|
@@ -39,6 +38,39 @@ describe Retriable do
|
|
|
39
38
|
expect { retriable { increment_tries_with_exception } }.to raise_error(StandardError)
|
|
40
39
|
expect(@tries).to eq(3)
|
|
41
40
|
end
|
|
41
|
+
|
|
42
|
+
it "passes on_give_up through the kernel extension" do
|
|
43
|
+
require_relative "../lib/retriable/core_ext/kernel"
|
|
44
|
+
received_reason = nil
|
|
45
|
+
handler = proc { |_e, _try, _elapsed, _interval, reason| received_reason = reason }
|
|
46
|
+
|
|
47
|
+
expect { retriable(tries: 1, on_give_up: handler) { increment_tries_with_exception } }
|
|
48
|
+
.to raise_error(StandardError)
|
|
49
|
+
|
|
50
|
+
expect(received_reason).to eq(:tries_exhausted)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# These two specs lock in the anonymous block forwarding (`&`) semantics
|
|
54
|
+
# across both delegation layers: Kernel#retriable_with_context ->
|
|
55
|
+
# Retriable.with_context. If the `&` is dropped at either layer, the
|
|
56
|
+
# block is not forwarded and the inner `block_given?` check at
|
|
57
|
+
# lib/retriable.rb:51 short-circuits, causing the block to never run.
|
|
58
|
+
it "forwards a block through Kernel#retriable_with_context" do
|
|
59
|
+
require_relative "../lib/retriable/core_ext/kernel"
|
|
60
|
+
Retriable.configure { |c| c.contexts[:sql] = { tries: 1 } }
|
|
61
|
+
|
|
62
|
+
retriable_with_context(:sql) { increment_tries }
|
|
63
|
+
|
|
64
|
+
expect(@tries).to eq(1)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "returns nil when Kernel#retriable_with_context is called without a block" do
|
|
68
|
+
require_relative "../lib/retriable/core_ext/kernel"
|
|
69
|
+
Retriable.configure { |c| c.contexts[:sql] = { tries: 1 } }
|
|
70
|
+
|
|
71
|
+
expect(retriable_with_context(:sql)).to be_nil
|
|
72
|
+
expect(@tries).to eq(0)
|
|
73
|
+
end
|
|
42
74
|
end
|
|
43
75
|
|
|
44
76
|
context "#retriable" do
|
|
@@ -51,9 +83,6 @@ describe Retriable do
|
|
|
51
83
|
|
|
52
84
|
it "raises a LocalJumpError if not given a block" do
|
|
53
85
|
expect { described_class.retriable }.to raise_error(LocalJumpError)
|
|
54
|
-
expect do
|
|
55
|
-
expect { described_class.retriable(timeout: 2) }.to raise_error(LocalJumpError)
|
|
56
|
-
end.to output(/timeout.*deprecated.*Retriable 4\.0/i).to_stderr
|
|
57
86
|
end
|
|
58
87
|
|
|
59
88
|
it "stops at first try if the block does not raise an exception" do
|
|
@@ -171,86 +200,8 @@ describe Retriable do
|
|
|
171
200
|
end.to raise_error(ArgumentError, /tries/)
|
|
172
201
|
end
|
|
173
202
|
|
|
174
|
-
it "
|
|
175
|
-
expect
|
|
176
|
-
expect { described_class.retriable(timeout: 1) { sleep(1.1) } }.to raise_error(Timeout::Error)
|
|
177
|
-
end.to output(/timeout.*deprecated.*Retriable 4\.0/i).to_stderr
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
context "timeout: deprecation" do
|
|
181
|
-
it "warns at most once per process across repeated retriable calls" do
|
|
182
|
-
original_stderr = $stderr
|
|
183
|
-
stderr = StringIO.new
|
|
184
|
-
begin
|
|
185
|
-
$stderr = stderr
|
|
186
|
-
|
|
187
|
-
described_class.retriable(timeout: 5) { :noop }
|
|
188
|
-
described_class.retriable(timeout: 5) { :noop }
|
|
189
|
-
described_class.retriable(timeout: 5) { :noop }
|
|
190
|
-
|
|
191
|
-
expect(stderr.string.scan("timeout:` option is deprecated").size).to eq(1)
|
|
192
|
-
ensure
|
|
193
|
-
$stderr = original_stderr
|
|
194
|
-
end
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
it "warns when timeout is passed to retriable" do
|
|
198
|
-
expect do
|
|
199
|
-
described_class.retriable(timeout: 5) { :noop }
|
|
200
|
-
end.to output(/timeout.*deprecated.*Retriable 4\.0/i).to_stderr
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
it "keeps applying timeout while deprecated" do
|
|
204
|
-
original_stderr = $stderr
|
|
205
|
-
begin
|
|
206
|
-
$stderr = StringIO.new
|
|
207
|
-
expect do
|
|
208
|
-
described_class.retriable(timeout: 0.05, tries: 1) { sleep(0.5) }
|
|
209
|
-
end.to raise_error(Timeout::Error)
|
|
210
|
-
ensure
|
|
211
|
-
$stderr = original_stderr
|
|
212
|
-
end
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
it "warns when timeout is supplied through with_override" do
|
|
216
|
-
expect do
|
|
217
|
-
described_class.with_override(timeout: 5) do
|
|
218
|
-
described_class.retriable { :noop }
|
|
219
|
-
end
|
|
220
|
-
end.to output(/timeout.*deprecated.*Retriable 4\.0/i).to_stderr
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
it "warns when timeout is supplied through configure" do
|
|
224
|
-
original_config = described_class.config
|
|
225
|
-
begin
|
|
226
|
-
expect do
|
|
227
|
-
described_class.configure { |config| config.timeout = 5 }
|
|
228
|
-
described_class.retriable { :noop }
|
|
229
|
-
end.to output(/timeout.*deprecated.*Retriable 4\.0/i).to_stderr
|
|
230
|
-
ensure
|
|
231
|
-
described_class.configure do |config|
|
|
232
|
-
original_config.to_h.each { |key, value| config.public_send("#{key}=", value) }
|
|
233
|
-
end
|
|
234
|
-
end
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
it "is silenced by Warning[:deprecated] = false", if: WARN_CATEGORY_SUPPORTED do
|
|
238
|
-
original = Warning[:deprecated]
|
|
239
|
-
begin
|
|
240
|
-
Warning[:deprecated] = false
|
|
241
|
-
expect do
|
|
242
|
-
described_class.retriable(timeout: 5) { :noop }
|
|
243
|
-
end.not_to output.to_stderr
|
|
244
|
-
ensure
|
|
245
|
-
Warning[:deprecated] = original
|
|
246
|
-
end
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
it "does not warn when timeout is absent" do
|
|
250
|
-
expect do
|
|
251
|
-
described_class.retriable { :noop }
|
|
252
|
-
end.not_to output.to_stderr
|
|
253
|
-
end
|
|
203
|
+
it "rejects timeout as an unknown option" do
|
|
204
|
+
expect { described_class.retriable(timeout: 1) { :noop } }.to raise_error(ArgumentError, /not a valid option/)
|
|
254
205
|
end
|
|
255
206
|
|
|
256
207
|
it "applies a randomized exponential backoff to each try" do
|
|
@@ -296,6 +247,187 @@ describe Retriable do
|
|
|
296
247
|
end
|
|
297
248
|
end
|
|
298
249
|
|
|
250
|
+
it "does not call on_retry when explicitly set to nil" do
|
|
251
|
+
callback_called = false
|
|
252
|
+
original_on_retry = described_class.config.on_retry
|
|
253
|
+
|
|
254
|
+
begin
|
|
255
|
+
described_class.configure do |c|
|
|
256
|
+
c.on_retry = proc { |_exception, _try, _elapsed_time, _next_interval| callback_called = true }
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
expect do
|
|
260
|
+
described_class.retriable(on_retry: nil, tries: 3) { increment_tries_with_exception }
|
|
261
|
+
end.to raise_error(StandardError)
|
|
262
|
+
|
|
263
|
+
expect(@tries).to eq(3)
|
|
264
|
+
expect(callback_called).to be(false)
|
|
265
|
+
ensure
|
|
266
|
+
described_class.configure do |c|
|
|
267
|
+
c.on_retry = original_on_retry
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
it "calls on_give_up with max elapsed time details before re-raising" do
|
|
273
|
+
described_class.configure { |c| c.sleep_disabled = false }
|
|
274
|
+
give_up_calls = []
|
|
275
|
+
on_give_up = proc do |exception, try, elapsed_time, next_interval, reason|
|
|
276
|
+
give_up_calls << [exception, try, elapsed_time, next_interval, reason]
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
expect do
|
|
280
|
+
described_class.retriable(
|
|
281
|
+
intervals: [1.0, 1.0],
|
|
282
|
+
max_elapsed_time: 0.5,
|
|
283
|
+
on_give_up: on_give_up,
|
|
284
|
+
) do
|
|
285
|
+
increment_tries_with_exception
|
|
286
|
+
end
|
|
287
|
+
end.to raise_error(StandardError)
|
|
288
|
+
|
|
289
|
+
exception, try, elapsed_time, next_interval, reason = give_up_calls.fetch(0)
|
|
290
|
+
expect(give_up_calls.size).to eq(1)
|
|
291
|
+
expect(exception).to be_a(StandardError)
|
|
292
|
+
expect(exception.message).to eq("StandardError occurred")
|
|
293
|
+
expect(try).to eq(1)
|
|
294
|
+
expect(elapsed_time).to be >= 0
|
|
295
|
+
expect(next_interval).to eq(1.0)
|
|
296
|
+
expect(reason).to eq(:max_elapsed_time)
|
|
297
|
+
expect(@tries).to eq(1)
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
it "calls on_give_up with tries exhausted details before re-raising" do
|
|
301
|
+
give_up_calls = []
|
|
302
|
+
on_give_up = proc do |exception, try, elapsed_time, next_interval, reason|
|
|
303
|
+
give_up_calls << [exception, try, elapsed_time, next_interval, reason]
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
expect do
|
|
307
|
+
described_class.retriable(tries: 2, on_give_up: on_give_up) { increment_tries_with_exception }
|
|
308
|
+
end.to raise_error(StandardError)
|
|
309
|
+
|
|
310
|
+
exception, try, elapsed_time, next_interval, reason = give_up_calls.fetch(0)
|
|
311
|
+
expect(give_up_calls.size).to eq(1)
|
|
312
|
+
expect(exception).to be_a(StandardError)
|
|
313
|
+
expect(exception.message).to eq("StandardError occurred")
|
|
314
|
+
expect(try).to eq(2)
|
|
315
|
+
expect(elapsed_time).to be >= 0
|
|
316
|
+
expect(next_interval).to be_nil
|
|
317
|
+
expect(reason).to eq(:tries_exhausted)
|
|
318
|
+
expect(@tries).to eq(2)
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
it "does not call on_give_up when the block eventually succeeds" do
|
|
322
|
+
callback_called = false
|
|
323
|
+
|
|
324
|
+
described_class.retriable(tries: 3, on_give_up: proc { callback_called = true }) do
|
|
325
|
+
increment_tries
|
|
326
|
+
raise StandardError if @tries < 2
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
expect(callback_called).to be(false)
|
|
330
|
+
expect(@tries).to eq(2)
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
it "does not call on_give_up for non-retriable exception types" do
|
|
334
|
+
callback_called = false
|
|
335
|
+
|
|
336
|
+
expect do
|
|
337
|
+
described_class.retriable(on_give_up: proc { callback_called = true }) do
|
|
338
|
+
increment_tries_with_exception(NonStandardError)
|
|
339
|
+
end
|
|
340
|
+
end.to raise_error(NonStandardError)
|
|
341
|
+
|
|
342
|
+
expect(callback_called).to be(false)
|
|
343
|
+
expect(@tries).to eq(1)
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
it "does not call on_give_up when retry_if rejects the exception" do
|
|
347
|
+
callback_called = false
|
|
348
|
+
|
|
349
|
+
expect do
|
|
350
|
+
described_class.retriable(
|
|
351
|
+
tries: 3,
|
|
352
|
+
retry_if: ->(_exception) { false },
|
|
353
|
+
on_give_up: proc { callback_called = true },
|
|
354
|
+
) do
|
|
355
|
+
increment_tries_with_exception
|
|
356
|
+
end
|
|
357
|
+
end.to raise_error(StandardError)
|
|
358
|
+
|
|
359
|
+
expect(callback_called).to be(false)
|
|
360
|
+
expect(@tries).to eq(1)
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
it "does not call on_give_up when explicitly set to false" do
|
|
364
|
+
callback_called = false
|
|
365
|
+
original_on_give_up = described_class.config.on_give_up
|
|
366
|
+
|
|
367
|
+
begin
|
|
368
|
+
described_class.configure do |c|
|
|
369
|
+
c.on_give_up = proc { callback_called = true }
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
expect do
|
|
373
|
+
described_class.retriable(on_give_up: false, tries: 1) { increment_tries_with_exception }
|
|
374
|
+
end.to raise_error(StandardError)
|
|
375
|
+
|
|
376
|
+
expect(callback_called).to be(false)
|
|
377
|
+
ensure
|
|
378
|
+
described_class.configure do |c|
|
|
379
|
+
c.on_give_up = original_on_give_up
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
it "does not call on_give_up when explicitly set to nil" do
|
|
385
|
+
callback_called = false
|
|
386
|
+
original_on_give_up = described_class.config.on_give_up
|
|
387
|
+
|
|
388
|
+
begin
|
|
389
|
+
described_class.configure do |c|
|
|
390
|
+
c.on_give_up = proc { callback_called = true }
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
expect do
|
|
394
|
+
described_class.retriable(on_give_up: nil, tries: 1) { increment_tries_with_exception }
|
|
395
|
+
end.to raise_error(StandardError)
|
|
396
|
+
|
|
397
|
+
expect(callback_called).to be(false)
|
|
398
|
+
ensure
|
|
399
|
+
described_class.configure do |c|
|
|
400
|
+
c.on_give_up = original_on_give_up
|
|
401
|
+
end
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
it "calls on_retry before on_give_up when giving up" do
|
|
406
|
+
events = []
|
|
407
|
+
|
|
408
|
+
expect do
|
|
409
|
+
described_class.retriable(
|
|
410
|
+
tries: 1,
|
|
411
|
+
on_retry: proc { events << :on_retry },
|
|
412
|
+
on_give_up: proc { events << :on_give_up },
|
|
413
|
+
) do
|
|
414
|
+
increment_tries_with_exception
|
|
415
|
+
end
|
|
416
|
+
end.to raise_error(StandardError)
|
|
417
|
+
|
|
418
|
+
expect(events).to eq(%i[on_retry on_give_up])
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
it "propagates exceptions raised inside on_give_up, replacing the original exception" do
|
|
422
|
+
handler = proc { raise "handler exploded" }
|
|
423
|
+
|
|
424
|
+
expect do
|
|
425
|
+
described_class.retriable(tries: 1, on_give_up: handler) { increment_tries_with_exception }
|
|
426
|
+
end.to raise_error(RuntimeError, "handler exploded")
|
|
427
|
+
|
|
428
|
+
expect(@tries).to eq(1)
|
|
429
|
+
end
|
|
430
|
+
|
|
299
431
|
context "with rand_factor 0.0 and an on_retry handler" do
|
|
300
432
|
let(:tries) { 6 }
|
|
301
433
|
let(:no_rand_timetable) { { 1 => 0.5, 2 => 0.75, 3 => 1.125 } }
|
|
@@ -375,6 +507,19 @@ describe Retriable do
|
|
|
375
507
|
end
|
|
376
508
|
end
|
|
377
509
|
|
|
510
|
+
context "with a Set :on parameter" do
|
|
511
|
+
it "retries each exception class in the Set" do
|
|
512
|
+
described_class.retriable(on: Set[StandardError, NonStandardError]) do
|
|
513
|
+
increment_tries
|
|
514
|
+
|
|
515
|
+
raise StandardError if @tries == 1
|
|
516
|
+
raise NonStandardError if @tries == 2
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
expect(@tries).to eq(3)
|
|
520
|
+
end
|
|
521
|
+
end
|
|
522
|
+
|
|
378
523
|
context "with a hash :on parameter" do
|
|
379
524
|
let(:on_hash) { { NonStandardError => /NonStandardError occurred/ } }
|
|
380
525
|
|
|
@@ -407,6 +552,20 @@ describe Retriable do
|
|
|
407
552
|
expect(@tries).to eq(1)
|
|
408
553
|
end
|
|
409
554
|
|
|
555
|
+
it "does not call on_give_up when exception class matches but message does not" do
|
|
556
|
+
callback_called = false
|
|
557
|
+
|
|
558
|
+
expect do
|
|
559
|
+
described_class.retriable(on: on_hash, on_give_up: proc { callback_called = true }) do
|
|
560
|
+
increment_tries
|
|
561
|
+
raise SecondNonStandardError, "not a match"
|
|
562
|
+
end
|
|
563
|
+
end.to raise_error(SecondNonStandardError, /not a match/)
|
|
564
|
+
|
|
565
|
+
expect(callback_called).to be(false)
|
|
566
|
+
expect(@tries).to eq(1)
|
|
567
|
+
end
|
|
568
|
+
|
|
410
569
|
it "successfully retries when the values are arrays of exception message patterns" do
|
|
411
570
|
exceptions = []
|
|
412
571
|
handler = ->(exception, try, _elapsed_time, _next_interval) { exceptions[try] = exception }
|
|
@@ -737,17 +896,15 @@ describe Retriable do
|
|
|
737
896
|
end
|
|
738
897
|
|
|
739
898
|
it "treats non-hash configured contexts as empty when override contexts are hash" do
|
|
740
|
-
|
|
741
|
-
described_class.configure { |c| c.contexts = nil }
|
|
899
|
+
described_class.configure { |c| c.contexts = nil }
|
|
742
900
|
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
end
|
|
746
|
-
|
|
747
|
-
expect(@tries).to eq(1)
|
|
748
|
-
ensure
|
|
749
|
-
described_class.configure { |c| c.contexts = {} }
|
|
901
|
+
described_class.with_override(contexts: { api: { tries: 1 } }) do
|
|
902
|
+
described_class.with_context(:api) { increment_tries }
|
|
750
903
|
end
|
|
904
|
+
|
|
905
|
+
expect(@tries).to eq(1)
|
|
906
|
+
ensure
|
|
907
|
+
described_class.configure { |c| c.contexts = {} }
|
|
751
908
|
end
|
|
752
909
|
|
|
753
910
|
it "ignores nil override contexts values in with_context" do
|
|
@@ -1017,6 +1174,31 @@ describe Retriable do
|
|
|
1017
1174
|
|
|
1018
1175
|
expect(other_thread_tries).to eq(3)
|
|
1019
1176
|
end
|
|
1177
|
+
|
|
1178
|
+
it "applies overridden on_give_up handlers" do
|
|
1179
|
+
callback_called = false
|
|
1180
|
+
|
|
1181
|
+
expect do
|
|
1182
|
+
described_class.with_override(on_give_up: proc { callback_called = true }) do
|
|
1183
|
+
described_class.retriable(tries: 1) { increment_tries_with_exception }
|
|
1184
|
+
end
|
|
1185
|
+
end.to raise_error(StandardError)
|
|
1186
|
+
|
|
1187
|
+
expect(callback_called).to be(true)
|
|
1188
|
+
end
|
|
1189
|
+
|
|
1190
|
+
it "applies on_give_up handlers configured via per-context overrides" do
|
|
1191
|
+
received_reason = nil
|
|
1192
|
+
handler = proc { |_e, _try, _elapsed, _interval, reason| received_reason = reason }
|
|
1193
|
+
|
|
1194
|
+
expect do
|
|
1195
|
+
described_class.with_override(contexts: { api: { tries: 1, on_give_up: handler } }) do
|
|
1196
|
+
described_class.with_context(:api) { increment_tries_with_exception }
|
|
1197
|
+
end
|
|
1198
|
+
end.to raise_error(StandardError)
|
|
1199
|
+
|
|
1200
|
+
expect(received_reason).to eq(:tries_exhausted)
|
|
1201
|
+
end
|
|
1020
1202
|
end
|
|
1021
1203
|
|
|
1022
1204
|
context "#with_context" do
|
|
@@ -1075,5 +1257,17 @@ describe Retriable do
|
|
|
1075
1257
|
described_class.with_context(:broken) { increment_tries }
|
|
1076
1258
|
expect(@tries).to eq(1)
|
|
1077
1259
|
end
|
|
1260
|
+
|
|
1261
|
+
it "invokes on_give_up configured on a context" do
|
|
1262
|
+
callback_called = false
|
|
1263
|
+
described_class.configure do |c|
|
|
1264
|
+
c.contexts[:flaky] = { tries: 1, on_give_up: proc { callback_called = true } }
|
|
1265
|
+
end
|
|
1266
|
+
|
|
1267
|
+
expect { described_class.with_context(:flaky) { increment_tries_with_exception } }
|
|
1268
|
+
.to raise_error(StandardError)
|
|
1269
|
+
|
|
1270
|
+
expect(callback_called).to be(true)
|
|
1271
|
+
end
|
|
1078
1272
|
end
|
|
1079
1273
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -7,21 +7,8 @@ require "pry"
|
|
|
7
7
|
require_relative "../lib/retriable"
|
|
8
8
|
require_relative "support/exceptions"
|
|
9
9
|
|
|
10
|
-
# Make Retriable's deprecation notices observable to RSpec's
|
|
11
|
-
# `output().to_stderr` matcher. On Ruby 3.0+ the `:deprecated` warning category
|
|
12
|
-
# is suppressed by default, which would hide the notices we want to assert on.
|
|
13
|
-
WARNING_DEPRECATION_SUPPORTED = defined?(Warning) && Warning.respond_to?(:[])
|
|
14
|
-
Warning[:deprecated] = true if WARNING_DEPRECATION_SUPPORTED
|
|
15
|
-
|
|
16
|
-
# Used by deprecation specs that only make sense on Rubies where `Kernel#warn`
|
|
17
|
-
# supports the `category:` keyword (added in Ruby 2.7).
|
|
18
|
-
WARN_CATEGORY_SUPPORTED = WARNING_DEPRECATION_SUPPORTED &&
|
|
19
|
-
Kernel.method(:warn).parameters.include?(%i[key category])
|
|
20
|
-
|
|
21
10
|
RSpec.configure do |config|
|
|
22
11
|
config.before(:each) do
|
|
23
12
|
srand(0)
|
|
24
|
-
Retriable::Config.timeout_deprecation_warned = false
|
|
25
|
-
Warning[:deprecated] = true if WARNING_DEPRECATION_SUPPORTED
|
|
26
13
|
end
|
|
27
14
|
end
|
metadata
CHANGED
|
@@ -1,56 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: retriable
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 4.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jack Chu
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
-
dependencies:
|
|
12
|
-
- !ruby/object:Gem::Dependency
|
|
13
|
-
name: bundler
|
|
14
|
-
requirement: !ruby/object:Gem::Requirement
|
|
15
|
-
requirements:
|
|
16
|
-
- - ">="
|
|
17
|
-
- !ruby/object:Gem::Version
|
|
18
|
-
version: '0'
|
|
19
|
-
type: :development
|
|
20
|
-
prerelease: false
|
|
21
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
-
requirements:
|
|
23
|
-
- - ">="
|
|
24
|
-
- !ruby/object:Gem::Version
|
|
25
|
-
version: '0'
|
|
26
|
-
- !ruby/object:Gem::Dependency
|
|
27
|
-
name: rspec
|
|
28
|
-
requirement: !ruby/object:Gem::Requirement
|
|
29
|
-
requirements:
|
|
30
|
-
- - "~>"
|
|
31
|
-
- !ruby/object:Gem::Version
|
|
32
|
-
version: '3'
|
|
33
|
-
type: :development
|
|
34
|
-
prerelease: false
|
|
35
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
-
requirements:
|
|
37
|
-
- - "~>"
|
|
38
|
-
- !ruby/object:Gem::Version
|
|
39
|
-
version: '3'
|
|
40
|
-
- !ruby/object:Gem::Dependency
|
|
41
|
-
name: listen
|
|
42
|
-
requirement: !ruby/object:Gem::Requirement
|
|
43
|
-
requirements:
|
|
44
|
-
- - "~>"
|
|
45
|
-
- !ruby/object:Gem::Version
|
|
46
|
-
version: '3.1'
|
|
47
|
-
type: :development
|
|
48
|
-
prerelease: false
|
|
49
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
-
requirements:
|
|
51
|
-
- - "~>"
|
|
52
|
-
- !ruby/object:Gem::Version
|
|
53
|
-
version: '3.1'
|
|
11
|
+
dependencies: []
|
|
54
12
|
description: Retriable is a simple DSL to retry failed code blocks with randomized
|
|
55
13
|
exponential backoff. This is especially useful when interacting with external APIs/services
|
|
56
14
|
or file system calls.
|
|
@@ -91,7 +49,8 @@ files:
|
|
|
91
49
|
homepage: https://github.com/kamui/retriable
|
|
92
50
|
licenses:
|
|
93
51
|
- MIT
|
|
94
|
-
metadata:
|
|
52
|
+
metadata:
|
|
53
|
+
rubygems_mfa_required: 'true'
|
|
95
54
|
rdoc_options: []
|
|
96
55
|
require_paths:
|
|
97
56
|
- lib
|
|
@@ -99,7 +58,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
99
58
|
requirements:
|
|
100
59
|
- - ">="
|
|
101
60
|
- !ruby/object:Gem::Version
|
|
102
|
-
version:
|
|
61
|
+
version: '3.2'
|
|
103
62
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
63
|
requirements:
|
|
105
64
|
- - ">="
|
|
@@ -110,9 +69,4 @@ rubygems_version: 4.0.3
|
|
|
110
69
|
specification_version: 4
|
|
111
70
|
summary: Retriable is a simple DSL to retry failed code blocks with randomized exponential
|
|
112
71
|
backoff
|
|
113
|
-
test_files:
|
|
114
|
-
- spec/config_spec.rb
|
|
115
|
-
- spec/exponential_backoff_spec.rb
|
|
116
|
-
- spec/retriable_spec.rb
|
|
117
|
-
- spec/spec_helper.rb
|
|
118
|
-
- spec/support/exceptions.rb
|
|
72
|
+
test_files: []
|