resque-retry 1.5.0 → 1.5.2
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 +5 -5
- data/.travis.yml +7 -9
- data/HISTORY.md +16 -5
- data/README.md +46 -14
- data/lib/resque-retry/version.rb +1 -1
- data/lib/resque/plugins/retry.rb +45 -5
- data/test/ignore_exceptions_test.rb +38 -0
- data/test/resque_inline_test.rb +23 -0
- data/test/retry_test.rb +14 -11
- data/test/test_jobs.rb +26 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d298842f059d9cd8ee69821e345e60d8a792e68f8f7b9fb2041508cd57e540c3
|
4
|
+
data.tar.gz: 203fc1782c1bdcf08858075f110e34421d1e5b805869514a36b3122739f2487f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 69bf34cb35ac34bf9975f4f2798dcb78dec39cfd0d373add776026aeaf5dbb594b70bfe2c0f8352701138a61095274413c3087dc14e251b96b117eea57c56207
|
7
|
+
data.tar.gz: b6602597785e8d13e1bb33883e852aece52d4b1e7ffc14f82843e42042c4219bfaa5cfeeec7a9a94176652b3bc59664535c218860127e7591ccd2f113ee80f83
|
data/.travis.yml
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
language: ruby
|
2
2
|
|
3
|
+
sudo: false
|
4
|
+
|
3
5
|
matrix:
|
4
6
|
allow_failures:
|
5
|
-
- rvm: jruby-
|
6
|
-
- rvm: rbx-2
|
7
|
+
- rvm: jruby-9.1.9.0
|
7
8
|
|
8
9
|
rvm:
|
9
|
-
-
|
10
|
-
- 2.
|
11
|
-
- 2.1
|
12
|
-
-
|
13
|
-
- 2.1.2
|
14
|
-
- jruby-19mode
|
15
|
-
- rbx-2
|
10
|
+
- 2.3.7
|
11
|
+
- 2.4.4
|
12
|
+
- 2.5.1
|
13
|
+
- jruby-9.1.9.0
|
data/HISTORY.md
CHANGED
@@ -1,4 +1,15 @@
|
|
1
|
-
|
1
|
+
# 1.5.2 (2018-07-16)
|
2
|
+
|
3
|
+
* Remove build support for `ruby < 2.3`, `jruby < 9.1` and `rbx`
|
4
|
+
* Improving custom retry criteria documentation (@iloveitaly)
|
5
|
+
|
6
|
+
# 1.5.1 (2018-01-07)
|
7
|
+
|
8
|
+
* Added build support for `ruby-2.2.x`, `ruby-2.3.x`, `ruby-2.4.x` and `ruby-2.5.x`
|
9
|
+
* Dropped build support for `ruby-1.9.3` and `ruby-2.0.0` (these versions are no unsupported)
|
10
|
+
* Fix some deprecation warnings in tests
|
11
|
+
* Feature: If no exact exception class is present in `@retry_exceptions` hash, try to find closest superclass (@fanfilmu)
|
12
|
+
* Feature: When running Resque inline, explicitly don't try to retry, don't touch Redis (@michaelglass)
|
2
13
|
|
3
14
|
# 1.5.0 (2015-10-24)
|
4
15
|
|
@@ -54,11 +65,11 @@
|
|
54
65
|
|
55
66
|
** !!! WARNING !!! INCLUDES NON-BACKWARDS COMPATIBLE CHANGES **
|
56
67
|
|
57
|
-
* Fixed issues related to
|
68
|
+
* Fixed issues related to infinite job retries and v1.20.0 of resque.
|
58
69
|
* Minimum gem dependency versions changed: resque >= 1.10.0, resque-scheduler >= 1.9.9
|
59
|
-
* Feature: Setting `@retry_job_delegate` allows you to
|
60
|
-
* Web interface will work without needing to `require` your job code. (n.b. less details
|
61
|
-
* IMPORTANT: `#identifier` method has been
|
70
|
+
* Feature: Setting `@retry_job_delegate` allows you to separate the original job from a the retry job. (@tanob/@jniesen)
|
71
|
+
* Web interface will work without needing to `require` your job code. (n.b. less details available via web).
|
72
|
+
* IMPORTANT: `#identifier` method has been namespaced to `#retry_identifier`.
|
62
73
|
* Bugfix: `Remove` button on retry web interface was not working.
|
63
74
|
* Feature: Allow `tagging` exceptions with a module instead of an exception class. (@tils - Tilmann Singer)
|
64
75
|
|
data/README.md
CHANGED
@@ -183,9 +183,10 @@ Here are a list of the options provided (click to jump):
|
|
183
183
|
* [Job Retry Identifier/Key](#retry_key)
|
184
184
|
* [Expire Retry Counters From Redis](#expire)
|
185
185
|
* [Try Again and Give Up Callbacks](#callbacks)
|
186
|
+
* [Ignored Exceptions](#ignored)
|
186
187
|
* [Debug Plugin Logging](#debug_log)
|
187
188
|
|
188
|
-
### <a name="retry_defaults"></a> Retry Defaults
|
189
|
+
### <a name="retry_defaults"></a> Retry Defaults
|
189
190
|
|
190
191
|
Retry the job **once** on failure, with zero delay.
|
191
192
|
```ruby
|
@@ -357,6 +358,8 @@ In the above example, Resque would retry any `DeliverSMS` jobs that throw any
|
|
357
358
|
type of error other than `NetworkError`. If the job throws a `NetworkError` it
|
358
359
|
will be marked as "failed" immediately.
|
359
360
|
|
361
|
+
You should use either `@fatal_exceptions` or `@retry_exceptions`. If you specify `@fatal_exceptions` the `@retry_exceptions` are ignored.
|
362
|
+
|
360
363
|
### <a name="custom_check"></a> Custom Retry Criteria Check Callbacks
|
361
364
|
|
362
365
|
You may define custom retry criteria callbacks:
|
@@ -368,11 +371,11 @@ class TurkWorker
|
|
368
371
|
@retry_exceptions = [NetworkError]
|
369
372
|
|
370
373
|
retry_criteria_check do |exception, *args|
|
371
|
-
if exception.message =~ /
|
372
|
-
|
373
|
-
else
|
374
|
-
true # its okay for a retry attempt to continue.
|
374
|
+
if exception.message =~ /SpecialErrorMessageToRetry/
|
375
|
+
return true
|
375
376
|
end
|
377
|
+
|
378
|
+
false
|
376
379
|
end
|
377
380
|
|
378
381
|
def self.perform(job_id)
|
@@ -385,9 +388,18 @@ Similar to the previous example, this job will retry if either a
|
|
385
388
|
`NetworkError` (or subclass) exception is thrown **or** any of the callbacks
|
386
389
|
return true.
|
387
390
|
|
391
|
+
You'll want to return false by default in the `retry_criteria_check` callback since
|
392
|
+
the result of this callback is OR'd with the result of your `retry_exceptions` or
|
393
|
+
`fatal_exceptions` configuration. In other words, if you returned true your
|
394
|
+
`retry_exceptions` configuration would never be used.
|
395
|
+
|
396
|
+
If you want to AND the result of `fatal_exceptions` or `retry_exceptions` with
|
397
|
+
custom retry criteria, you'll need to implement your own logic in a `retry_criteria_check`
|
398
|
+
to check for `fatal_exceptions` or `retry_exceptions`.
|
399
|
+
|
388
400
|
You can also register a retry criteria check with a Symbol if the method is
|
389
401
|
already defined on the job class:
|
390
|
-
```
|
402
|
+
```ruby
|
391
403
|
class AlwaysRetryJob
|
392
404
|
extend Resque::Plugins::Retry
|
393
405
|
|
@@ -397,8 +409,9 @@ class AlwaysRetryJob
|
|
397
409
|
true
|
398
410
|
end
|
399
411
|
end
|
412
|
+
```
|
400
413
|
|
401
|
-
Use `@retry_exceptions = []` to **only** use your custom retry criteria checks
|
414
|
+
Use `@retry_exceptions = []` and `@fatal_exceptions = []` to **only** use your custom retry criteria checks
|
402
415
|
to determine if the job should retry.
|
403
416
|
|
404
417
|
NB: Your callback must be able to accept the exception and job arguments as
|
@@ -419,7 +432,7 @@ class DeliverViaSMSC
|
|
419
432
|
[999, mt_message]
|
420
433
|
end
|
421
434
|
|
422
|
-
self.perform(smsc_id, mt_message)
|
435
|
+
def self.perform(smsc_id, mt_message)
|
423
436
|
heavy_lifting
|
424
437
|
end
|
425
438
|
end
|
@@ -439,7 +452,7 @@ class DeliverViaSMSC
|
|
439
452
|
[999, mt_message + exception.message]
|
440
453
|
end
|
441
454
|
|
442
|
-
self.perform(smsc_id, mt_message)
|
455
|
+
def self.perform(smsc_id, mt_message)
|
443
456
|
heavy_lifting
|
444
457
|
end
|
445
458
|
end
|
@@ -466,7 +479,7 @@ class DeliverSMS
|
|
466
479
|
"#{mobile_number}:#{mt_id}"
|
467
480
|
end
|
468
481
|
|
469
|
-
self.perform(mt_id, mobile_number, message)
|
482
|
+
def self.perform(mt_id, mobile_number, message)
|
470
483
|
heavy_lifting
|
471
484
|
end
|
472
485
|
end
|
@@ -482,7 +495,7 @@ class DeliverSMS
|
|
482
495
|
@queue = :mt_messages
|
483
496
|
@expire_retry_key_after = 3600 # expire key after `retry_delay` plus 1 hour
|
484
497
|
|
485
|
-
self.perform(mt_id, mobile_number, message)
|
498
|
+
def self.perform(mt_id, mobile_number, message)
|
486
499
|
heavy_lifting
|
487
500
|
end
|
488
501
|
end
|
@@ -512,7 +525,7 @@ _not_ retrying, you can add a `give_up_callback`:
|
|
512
525
|
```ruby
|
513
526
|
class LoggedJob
|
514
527
|
extend Resque::Plugins::Retry
|
515
|
-
|
528
|
+
|
516
529
|
give_up_callback do |exception, *args|
|
517
530
|
logger.error("Received #{exception}, job #{self.name} failed with #{args}")
|
518
531
|
end
|
@@ -524,10 +537,10 @@ the job class:
|
|
524
537
|
```ruby
|
525
538
|
class LoggedJob
|
526
539
|
extend Resque::Plugins::Retry
|
527
|
-
|
540
|
+
|
528
541
|
give_up_callback :log_give_up
|
529
542
|
|
530
|
-
def self.log_give_up(
|
543
|
+
def self.log_give_up(exception, *args)
|
531
544
|
logger.error("Received #{exception}, job #{self.name} failed with #{args}")
|
532
545
|
end
|
533
546
|
end
|
@@ -557,6 +570,25 @@ Warning: Make sure your callbacks do not throw any exceptions. If they do,
|
|
557
570
|
subsequent callbacks will not be triggered, and the job will not be retried
|
558
571
|
(if it was trying again). The retry counter also will not be reset.
|
559
572
|
|
573
|
+
### <a name="ignored"></a> Ignored Exceptions
|
574
|
+
If there is an exception for which you want to retry, but you don't want it to
|
575
|
+
increment your retry counter, you can add it to `@ignore_exceptions`.
|
576
|
+
|
577
|
+
One use case: Restarting your workers triggers a `Resque::TermException`. You
|
578
|
+
may want your workers to retry the job that they were working on, but without
|
579
|
+
incrementing the retry counter.
|
580
|
+
|
581
|
+
```ruby
|
582
|
+
class RestartResilientJob
|
583
|
+
extend Resque::Plugins::Retry
|
584
|
+
|
585
|
+
@retry_exceptions = [Resque::TermException]
|
586
|
+
@ignore_exceptions = [Resque::TermException]
|
587
|
+
end
|
588
|
+
```
|
589
|
+
|
590
|
+
Reminder: `@ignore_exceptions` should be a subset of `@retry_exceptions`.
|
591
|
+
|
560
592
|
### <a name="debug_log"></a> Debug Plugin Logging
|
561
593
|
|
562
594
|
The inner-workings of the plugin are output to the Resque [Logger](https://github.com/resque/resque/wiki/Logging)
|
data/lib/resque-retry/version.rb
CHANGED
data/lib/resque/plugins/retry.rb
CHANGED
@@ -43,13 +43,34 @@ module Resque
|
|
43
43
|
# @api public
|
44
44
|
class AmbiguousRetryStrategyException < StandardError; end
|
45
45
|
|
46
|
+
# Raised if there is a problem with the configuration of resque-retry.
|
47
|
+
#
|
48
|
+
# @api public
|
49
|
+
class RetryConfigurationException < StandardError; end
|
50
|
+
|
46
51
|
# Fail fast, when extended, if the "receiver" is misconfigured
|
47
52
|
#
|
48
53
|
# @api private
|
49
54
|
def self.extended(receiver)
|
50
|
-
|
55
|
+
retry_exceptions = receiver.instance_variable_get('@retry_exceptions')
|
56
|
+
fatal_exceptions = receiver.instance_variable_get('@fatal_exceptions')
|
57
|
+
ignore_exceptions = receiver.instance_variable_get('@ignore_exceptions')
|
58
|
+
|
59
|
+
if fatal_exceptions && retry_exceptions
|
51
60
|
raise AmbiguousRetryStrategyException.new(%{You can't define both "@fatal_exceptions" and "@retry_exceptions"})
|
52
61
|
end
|
62
|
+
|
63
|
+
# Check that ignore_exceptions is a subset of retry_exceptions
|
64
|
+
if retry_exceptions.is_a?(Hash)
|
65
|
+
exceptions = retry_exceptions.keys
|
66
|
+
else
|
67
|
+
exceptions = Array(retry_exceptions)
|
68
|
+
end
|
69
|
+
|
70
|
+
excess_exceptions = Array(ignore_exceptions) - exceptions
|
71
|
+
unless excess_exceptions.empty?
|
72
|
+
raise RetryConfigurationException, "The following exceptions are defined in @ignore_exceptions but not in @retry_exceptions: #{excess_exceptions.join(', ')}."
|
73
|
+
end
|
53
74
|
end
|
54
75
|
|
55
76
|
# Copy retry criteria checks, try again callbacks, and give up callbacks
|
@@ -115,13 +136,18 @@ module Resque
|
|
115
136
|
|
116
137
|
# @abstract
|
117
138
|
# Number of seconds to delay until the job is retried
|
139
|
+
# If @retry_exceptions is a Hash and there is no delay defined for exception_class,
|
140
|
+
# looks for closest superclass and assigns it's delay to @retry_exceptions[exception_class]
|
118
141
|
#
|
119
142
|
# @return [Number] number of seconds to delay
|
120
143
|
#
|
121
144
|
# @api public
|
122
145
|
def retry_delay(exception_class = nil)
|
123
146
|
if @retry_exceptions.is_a?(Hash)
|
124
|
-
delay = @retry_exceptions[exception_class]
|
147
|
+
delay = @retry_exceptions[exception_class] ||= begin
|
148
|
+
relevant_definitions = @retry_exceptions.select { |ex| exception_class <= ex }
|
149
|
+
relevant_definitions.any? ? relevant_definitions.sort.first[1] : 0
|
150
|
+
end
|
125
151
|
# allow an array of delays.
|
126
152
|
delay.is_a?(Array) ? delay[retry_attempt] || delay.last : delay
|
127
153
|
else
|
@@ -131,7 +157,7 @@ module Resque
|
|
131
157
|
|
132
158
|
# @abstract
|
133
159
|
# Number of seconds to sleep after job is requeued
|
134
|
-
#
|
160
|
+
#
|
135
161
|
# @return [Number] number of seconds to sleep
|
136
162
|
#
|
137
163
|
# @api public
|
@@ -264,7 +290,7 @@ module Resque
|
|
264
290
|
# if the retry limit was reached, dont bother checking anything else.
|
265
291
|
if retry_limit_reached?
|
266
292
|
log_message 'retry limit reached', args, exception
|
267
|
-
return false
|
293
|
+
return false
|
268
294
|
end
|
269
295
|
|
270
296
|
# We always want to retry if the exception matches.
|
@@ -369,7 +395,7 @@ module Resque
|
|
369
395
|
|
370
396
|
# remember that this job is now being retried. before_perform_retry will increment
|
371
397
|
# this so it represents the retry count, and MultipleWithRetrySuppression uses
|
372
|
-
# the existence of this to determine if the job should be sent to the
|
398
|
+
# the existence of this to determine if the job should be sent to the
|
373
399
|
# parent failure backend (e.g. failed queue) or not. Removing this means
|
374
400
|
# jobs that fail before ::perform will be both retried and sent to the failed queue.
|
375
401
|
Resque.redis.setnx(redis_retry_key(*args), -1)
|
@@ -406,6 +432,7 @@ module Resque
|
|
406
432
|
#
|
407
433
|
# @api private
|
408
434
|
def before_perform_retry(*args)
|
435
|
+
return if Resque.inline?
|
409
436
|
log_message 'before_perform_retry', args
|
410
437
|
@on_failure_retry_hook_already_called = false
|
411
438
|
|
@@ -428,6 +455,7 @@ module Resque
|
|
428
455
|
#
|
429
456
|
# @api private
|
430
457
|
def after_perform_retry(*args)
|
458
|
+
return if Resque.inline?
|
431
459
|
log_message 'after_perform_retry, clearing retry key', args
|
432
460
|
clean_retry_key(*args)
|
433
461
|
end
|
@@ -443,6 +471,7 @@ module Resque
|
|
443
471
|
#
|
444
472
|
# @api private
|
445
473
|
def on_failure_retry(exception, *args)
|
474
|
+
return if Resque.inline?
|
446
475
|
log_message 'on_failure_retry', args, exception
|
447
476
|
if exception.is_a?(Resque::DirtyExit)
|
448
477
|
# This hook is called from a worker processes, not the job process
|
@@ -453,6 +482,13 @@ module Resque
|
|
453
482
|
return
|
454
483
|
end
|
455
484
|
|
485
|
+
# If we are "ignoring" the exception, then we decrement the retry
|
486
|
+
# counter, so that the current attempt didn't count toward the retry
|
487
|
+
# counter.
|
488
|
+
if ignore_exceptions.include?(exception.class)
|
489
|
+
@retry_attempt = Resque.redis.decr(redis_retry_key(*args))
|
490
|
+
end
|
491
|
+
|
456
492
|
if retry_criteria_valid?(exception, *args)
|
457
493
|
try_again(exception, *args)
|
458
494
|
else
|
@@ -584,6 +620,10 @@ module Resque
|
|
584
620
|
end
|
585
621
|
end
|
586
622
|
|
623
|
+
def ignore_exceptions
|
624
|
+
@ignore_exceptions ||= []
|
625
|
+
end
|
626
|
+
|
587
627
|
# Helper to call functions that may be passed as Symbols or Procs. If
|
588
628
|
# a symbol, it is assumed to refer to a method that is already defined
|
589
629
|
# on this class.
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class IgnoreExceptionsTest < Minitest::Test
|
4
|
+
def setup
|
5
|
+
Resque.redis.flushall
|
6
|
+
@worker = Resque::Worker.new(:testing)
|
7
|
+
@worker.register_worker
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_ignore_exceptions
|
11
|
+
Resque.enqueue(IgnoreExceptionsJob)
|
12
|
+
retry_key = IgnoreExceptionsJob.redis_retry_key
|
13
|
+
|
14
|
+
IgnoreExceptionsJob.stubs(:perform).raises(AnotherCustomException)
|
15
|
+
perform_next_job(@worker)
|
16
|
+
assert_equal '0', Resque.redis.get(retry_key), 'retry counter'
|
17
|
+
|
18
|
+
IgnoreExceptionsJob.stubs(:perform).raises(AnotherCustomException)
|
19
|
+
perform_next_job(@worker)
|
20
|
+
assert_equal '1', Resque.redis.get(retry_key), 'retry counter'
|
21
|
+
|
22
|
+
IgnoreExceptionsJob.stubs(:perform).raises(CustomException)
|
23
|
+
perform_next_job(@worker)
|
24
|
+
assert_equal '1', Resque.redis.get(retry_key), 'retry counter'
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_ignore_exception_configuration_1
|
28
|
+
assert_raises Resque::Plugins::Retry::RetryConfigurationException do
|
29
|
+
IgnoreExceptionsImproperlyConfiguredJob1.extend(Resque::Plugins::Retry)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_ignore_exception_configuration_2
|
34
|
+
assert_raises Resque::Plugins::Retry::RetryConfigurationException do
|
35
|
+
IgnoreExceptionsImproperlyConfiguredJob2.extend(Resque::Plugins::Retry)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ResqueInlineTest < Minitest::Test
|
4
|
+
def setup
|
5
|
+
Resque.inline = true
|
6
|
+
Resque.expects(:redis).never
|
7
|
+
end
|
8
|
+
|
9
|
+
def teardown
|
10
|
+
Resque.inline = false
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_runs_inline
|
14
|
+
GoodJob.expects :perform
|
15
|
+
Resque.enqueue(GoodJob)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_fails_inline
|
19
|
+
assert_raises CustomException do
|
20
|
+
Resque.enqueue(RetryCustomExceptionsJob, 'CustomException')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/test/retry_test.rb
CHANGED
@@ -18,8 +18,8 @@ class RetryTest < Minitest::Test
|
|
18
18
|
def test_default_settings
|
19
19
|
assert_equal 1, RetryDefaultSettingsJob.retry_limit, 'default retry limit'
|
20
20
|
assert_equal 0, RetryDefaultSettingsJob.retry_attempt, 'default number of retry attempts'
|
21
|
-
|
22
|
-
|
21
|
+
assert_nil RetryDefaultSettingsJob.fatal_exceptions, 'default fatal exceptions; nil = none'
|
22
|
+
assert_nil RetryDefaultSettingsJob.retry_exceptions, 'default retry exceptions; nil = any'
|
23
23
|
assert_equal 0, RetryDefaultSettingsJob.retry_delay, 'default seconds until retry'
|
24
24
|
end
|
25
25
|
|
@@ -223,7 +223,7 @@ class RetryTest < Minitest::Test
|
|
223
223
|
|
224
224
|
assert job_from_retry_queue = Resque.pop(:testing_retry)
|
225
225
|
assert_equal ['arg1'], job_from_retry_queue['args']
|
226
|
-
|
226
|
+
assert_nil Resque.redis.get(JobWithRetryQueue.redis_retry_key('arg1'))
|
227
227
|
end
|
228
228
|
|
229
229
|
def test_clean_retry_key_should_splat_args
|
@@ -244,14 +244,14 @@ class RetryTest < Minitest::Test
|
|
244
244
|
def test_delete_redis_key_when_job_is_successful
|
245
245
|
Resque.enqueue(GoodJob, 'arg1')
|
246
246
|
|
247
|
-
|
247
|
+
assert_nil Resque.redis.get(GoodJob.redis_retry_key('arg1'))
|
248
248
|
perform_next_job(@worker)
|
249
|
-
|
249
|
+
assert_nil Resque.redis.get(GoodJob.redis_retry_key('arg1'))
|
250
250
|
end
|
251
251
|
|
252
252
|
def test_delete_redis_key_after_final_failed_retry
|
253
253
|
Resque.enqueue(FailFiveTimesJob, 'yarrrr')
|
254
|
-
|
254
|
+
assert_nil Resque.redis.get(FailFiveTimesJob.redis_retry_key('yarrrr'))
|
255
255
|
|
256
256
|
perform_next_job(@worker)
|
257
257
|
assert_equal '0', Resque.redis.get(FailFiveTimesJob.redis_retry_key('yarrrr'))
|
@@ -262,7 +262,7 @@ class RetryTest < Minitest::Test
|
|
262
262
|
5.times do
|
263
263
|
perform_next_job(@worker)
|
264
264
|
end
|
265
|
-
|
265
|
+
assert_nil Resque.redis.get(FailFiveTimesJob.redis_retry_key('yarrrr'))
|
266
266
|
|
267
267
|
assert_equal 5, Resque.info[:failed], 'failed jobs'
|
268
268
|
assert_equal 6, Resque.info[:processed], 'processed job'
|
@@ -286,9 +286,12 @@ class RetryTest < Minitest::Test
|
|
286
286
|
|
287
287
|
def test_retry_delay
|
288
288
|
assert_equal 3, NormalRetryCountJob.retry_delay
|
289
|
-
assert_equal 7, PerExceptionClassRetryCountJob.retry_delay(
|
290
|
-
assert_equal
|
291
|
-
assert_equal
|
289
|
+
assert_equal 7, PerExceptionClassRetryCountJob.retry_delay(StandardError)
|
290
|
+
assert_equal 7, PerExceptionClassRetryCountJob.retry_delay(CustomException)
|
291
|
+
assert_equal 11, PerExceptionClassRetryCountJob.retry_delay(AnotherCustomException)
|
292
|
+
assert_equal 13, PerExceptionClassRetryCountJob.retry_delay(HierarchyCustomException)
|
293
|
+
|
294
|
+
assert_equal 7, PerExceptionClassRetryCountJob.instance_variable_get("@retry_exceptions")[CustomException]
|
292
295
|
end
|
293
296
|
|
294
297
|
def test_expire_key_set
|
@@ -327,7 +330,7 @@ class RetryTest < Minitest::Test
|
|
327
330
|
job.fail(Resque::DirtyExit.new)
|
328
331
|
end
|
329
332
|
|
330
|
-
|
333
|
+
assert_nil @worker.reserve
|
331
334
|
end
|
332
335
|
end
|
333
336
|
end
|
data/test/test_jobs.rb
CHANGED
@@ -496,7 +496,7 @@ class PerExceptionClassRetryCountJob
|
|
496
496
|
|
497
497
|
@queue = :testing
|
498
498
|
@retry_limit = 3
|
499
|
-
@retry_exceptions = {
|
499
|
+
@retry_exceptions = { StandardError => 7, AnotherCustomException => 11, HierarchyCustomException => 13 }
|
500
500
|
|
501
501
|
def self.perform
|
502
502
|
raise RuntimeError, 'I always fail with a RuntimeError'
|
@@ -579,3 +579,28 @@ class RetryCallbacksJob
|
|
579
579
|
|
580
580
|
give_up_callback :on_give_up_c
|
581
581
|
end
|
582
|
+
|
583
|
+
class IgnoreExceptionsJob
|
584
|
+
extend Resque::Plugins::Retry
|
585
|
+
@queue = :testing
|
586
|
+
@ignore_exceptions = [CustomException]
|
587
|
+
@retry_exceptions = [CustomException, AnotherCustomException]
|
588
|
+
@retry_limit = 3
|
589
|
+
|
590
|
+
def self.perform
|
591
|
+
"Hello, World!"
|
592
|
+
end
|
593
|
+
end
|
594
|
+
|
595
|
+
class IgnoreExceptionsImproperlyConfiguredJob1
|
596
|
+
# Manually extend Resque::Plugins::Retry in the test code to catch the
|
597
|
+
# exception.
|
598
|
+
@ignore_exceptions = [CustomException]
|
599
|
+
end
|
600
|
+
|
601
|
+
class IgnoreExceptionsImproperlyConfiguredJob2
|
602
|
+
# Manually extend Resque::Plugins::Retry in the test code to catch the
|
603
|
+
# exception.
|
604
|
+
@ignore_exceptions = [CustomException]
|
605
|
+
@retry_exceptions = { AnotherCustomException => 0 }
|
606
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resque-retry
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luke Antins
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2018-07-16 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: resque
|
@@ -181,8 +181,10 @@ files:
|
|
181
181
|
- lib/resque/plugins/retry/logging.rb
|
182
182
|
- resque-retry.gemspec
|
183
183
|
- test/exponential_backoff_test.rb
|
184
|
+
- test/ignore_exceptions_test.rb
|
184
185
|
- test/multiple_failure_test.rb
|
185
186
|
- test/redis-test.conf
|
187
|
+
- test/resque_inline_test.rb
|
186
188
|
- test/resque_test.rb
|
187
189
|
- test/retry_callbacks_test.rb
|
188
190
|
- test/retry_criteria_test.rb
|
@@ -214,10 +216,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
214
216
|
version: '0'
|
215
217
|
requirements: []
|
216
218
|
rubyforge_project:
|
217
|
-
rubygems_version: 2.
|
219
|
+
rubygems_version: 2.7.6
|
218
220
|
signing_key:
|
219
221
|
specification_version: 4
|
220
222
|
summary: A resque plugin; provides retry, delay and exponential backoff support for
|
221
223
|
resque jobs.
|
222
224
|
test_files: []
|
223
|
-
has_rdoc: false
|