resque-retry 1.2.1 → 1.3.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/.travis.yml +1 -0
- data/HISTORY.md +7 -0
- data/README.md +26 -7
- data/examples/demo/Rakefile +1 -1
- data/lib/resque-retry.rb +1 -1
- data/lib/resque-retry/server.rb +1 -1
- data/lib/resque-retry/version.rb +1 -1
- data/lib/resque/plugins/retry.rb +43 -8
- data/resque-retry.gemspec +1 -1
- data/test/retry_test.rb +27 -19
- data/test/test_jobs.rb +32 -13
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 66d34a270a535f97586c21a6c259d780c7a1ce9f
|
4
|
+
data.tar.gz: 9ab5f4591d2a99e262cc1ab2501d70e845f710aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 03b4b70d9ef0e69d46d738fb3b6c1dd987e3e0e46cf3a2724300b50e1fbdcfc9f44d2af1b18b53999a21e74d48e335fe1a689e9885e14e784070ad5384f1fcac
|
7
|
+
data.tar.gz: 781a313ebd129ad8db24df9822b47bec750879aa2fa1abcc524df00228767c6a50eca03c780b19aee8e576304fcb294fe83f963af8fb75beacf4cb89b3f631fb
|
data/.travis.yml
CHANGED
data/HISTORY.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
1
|
## HEAD
|
2
2
|
|
3
|
+
## 1.3.0 (2014-07-25)
|
4
|
+
|
5
|
+
* Adjust gem dependency on `resque-scheduler` to ~> 3.0
|
6
|
+
* Deprecated: `args_for_retry` in favor of `retry_args` (will output deprecation warnings if your using the older method).
|
7
|
+
* Feature: Allow changing the args for a given exception using `retry_args_for_exception` (@jonp)
|
8
|
+
* Feature: Allow setting `@expire_retry_key_after` on the fly (@orenmazor)
|
9
|
+
|
3
10
|
## 1.2.1 (2014-06-09)
|
4
11
|
|
5
12
|
* Fixed Kernel.rand: "invalid argument - 0.0 (ArgumentError)" error with "ExponentialBackoff" (on "Rubinius") when `retry_delay_multiplicand_min` and `retry_delay_multiplicand_max` were the same value (@saizai)
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
resque-retry
|
2
2
|
============
|
3
3
|
|
4
|
-
A [Resque][rq] plugin. Requires Resque ~> 1.25 & [resque-scheduler][rqs] ~>
|
4
|
+
A [Resque][rq] plugin. Requires Resque ~> 1.25 & [resque-scheduler][rqs] ~> 3.0.
|
5
5
|
|
6
6
|
resque-retry provides retry, delay and exponential backoff support for
|
7
7
|
resque jobs.
|
@@ -28,7 +28,7 @@ If you're using [Bundler][bundler] to manage your dependencies, you should add `
|
|
28
28
|
Add this to your `Rakefile`:
|
29
29
|
```ruby
|
30
30
|
require 'resque/tasks'
|
31
|
-
require '
|
31
|
+
require 'resque/scheduler/tasks'
|
32
32
|
```
|
33
33
|
|
34
34
|
The delay between retry attempts is provided by [resque-scheduler][rqs].
|
@@ -120,8 +120,8 @@ run Resque::Server.new
|
|
120
120
|
Retry Options & Logic
|
121
121
|
---------------------
|
122
122
|
|
123
|
-
Please take a look at the yardoc/code
|
124
|
-
wish to override.
|
123
|
+
Please take a look at the [yardoc](http://rubydoc.info/gems/resque-retry)/code
|
124
|
+
for more details on methods you may wish to override.
|
125
125
|
|
126
126
|
Customisation is pretty easy, the below examples should give you
|
127
127
|
some ideas =), adapt for your own usage and feel free to pick and mix!
|
@@ -332,7 +332,7 @@ job should retry.
|
|
332
332
|
|
333
333
|
### Retry Arguments
|
334
334
|
|
335
|
-
You may override `
|
335
|
+
You may override `retry_args`, which is passed the current
|
336
336
|
job arguments, to modify the arguments for the next retry attempt.
|
337
337
|
```ruby
|
338
338
|
class DeliverViaSMSC
|
@@ -340,7 +340,7 @@ class DeliverViaSMSC
|
|
340
340
|
@queue = :mt_smsc_messages
|
341
341
|
|
342
342
|
# retry using the emergency SMSC.
|
343
|
-
def self.
|
343
|
+
def self.retry_args(smsc_id, mt_message)
|
344
344
|
[999, mt_message]
|
345
345
|
end
|
346
346
|
|
@@ -350,6 +350,25 @@ class DeliverViaSMSC
|
|
350
350
|
end
|
351
351
|
```
|
352
352
|
|
353
|
+
Alternatively, if you require finer control of the args based on the
|
354
|
+
exception thrown, you may override `retry_args_for_exception`, which is passed
|
355
|
+
the exception and the current job arguments, to modify the arguments for the
|
356
|
+
next retry attempt.
|
357
|
+
```ruby
|
358
|
+
class DeliverViaSMSC
|
359
|
+
extend Resque::Plugins::Retry
|
360
|
+
@queue = :mt_smsc_messages
|
361
|
+
|
362
|
+
# retry using the emergency SMSC.
|
363
|
+
def self.retry_args_for_exception(exception, smsc_id, mt_message)
|
364
|
+
[999, mt_message + exception.message]
|
365
|
+
end
|
366
|
+
|
367
|
+
self.perform(smsc_id, mt_message)
|
368
|
+
heavy_lifting
|
369
|
+
end
|
370
|
+
end
|
371
|
+
```
|
353
372
|
### Job Retry Identifier/Key
|
354
373
|
|
355
374
|
The retry attempt is incremented and stored in a Redis key. The key is
|
@@ -401,7 +420,7 @@ This saves you from having to run a "house cleaning" or "errand" job.
|
|
401
420
|
The expiary timeout is "pushed forward" or "touched" after each failure to
|
402
421
|
ensure its not expired too soon.
|
403
422
|
|
404
|
-
### Debug
|
423
|
+
### Debug Plugin Logging
|
405
424
|
|
406
425
|
The inner-workings of the plugin are output to the Resque [Logger](https://github.com/resque/resque/wiki/Logging)
|
407
426
|
when `Resque.logger.level` is set to `Logger::DEBUG`.
|
data/examples/demo/Rakefile
CHANGED
@@ -12,7 +12,7 @@ require 'resque/failure/redis'
|
|
12
12
|
|
13
13
|
# Require Rakefile related resque things.
|
14
14
|
require 'resque/tasks'
|
15
|
-
require '
|
15
|
+
require 'resque/scheduler/tasks'
|
16
16
|
|
17
17
|
# Enable resque-retry failure backend.
|
18
18
|
Resque::Failure::MultipleWithRetrySuppression.classes = [Resque::Failure::Redis]
|
data/lib/resque-retry.rb
CHANGED
data/lib/resque-retry/server.rb
CHANGED
data/lib/resque-retry/version.rb
CHANGED
data/lib/resque/plugins/retry.rb
CHANGED
@@ -154,8 +154,27 @@ module Resque
|
|
154
154
|
# @return [Array] new job arguments
|
155
155
|
#
|
156
156
|
# @api public
|
157
|
-
def
|
158
|
-
|
157
|
+
def retry_args(*args)
|
158
|
+
# Here for backwards compatibility. If an "args_for_retry" method exists
|
159
|
+
# invoke it, but warn that it is deprecated (and will be removed in a
|
160
|
+
# future revision)
|
161
|
+
if respond_to?(:args_for_retry)
|
162
|
+
warn "`Resque::Plugins::Retry#args_for_retry` is deprecated, please use `Resque::Plugins::Retry#retry_args` instead."
|
163
|
+
args_for_retry(*args)
|
164
|
+
else
|
165
|
+
args
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# @abstract
|
170
|
+
# Modify the arguments used to retry the job based on the exception.
|
171
|
+
# Use this to do something other than try the exact same job again.
|
172
|
+
#
|
173
|
+
# @return [Array] new job arguments
|
174
|
+
#
|
175
|
+
# @api public
|
176
|
+
def retry_args_for_exception(exception, *args)
|
177
|
+
retry_args(*args)
|
159
178
|
end
|
160
179
|
|
161
180
|
# Convenience method to test whether you may retry on a given
|
@@ -223,6 +242,14 @@ module Resque
|
|
223
242
|
end
|
224
243
|
end
|
225
244
|
|
245
|
+
# @abstract
|
246
|
+
# The number of seconds to set the TTL to on the resque-retry key in redis
|
247
|
+
#
|
248
|
+
# @return [Number] number of seconds
|
249
|
+
#
|
250
|
+
# @api public
|
251
|
+
attr_reader :expire_retry_key_after
|
252
|
+
|
226
253
|
# Test if the retry criteria is valid
|
227
254
|
#
|
228
255
|
# @param [Exception] exception
|
@@ -322,11 +349,13 @@ module Resque
|
|
322
349
|
# jobs that fail before ::perform will be both retried and sent to the failed queue.
|
323
350
|
Resque.redis.setnx(redis_retry_key(*args), -1)
|
324
351
|
|
352
|
+
retry_args = retry_args_for_exception(exception, *args)
|
353
|
+
|
325
354
|
if temp_retry_delay <= 0
|
326
355
|
# If the delay is 0, no point passing it through the scheduler
|
327
|
-
Resque.enqueue(retry_in_queue, *
|
356
|
+
Resque.enqueue(retry_in_queue, *retry_args)
|
328
357
|
else
|
329
|
-
Resque.enqueue_in(temp_retry_delay, retry_in_queue, *
|
358
|
+
Resque.enqueue_in(temp_retry_delay, retry_in_queue, *retry_args)
|
330
359
|
end
|
331
360
|
|
332
361
|
# remove retry key from redis if we handed retry off to another queue.
|
@@ -338,7 +367,8 @@ module Resque
|
|
338
367
|
|
339
368
|
# Resque before_perform hook
|
340
369
|
#
|
341
|
-
# Increments and
|
370
|
+
# Increments `@retry_attempt` count and updates the "retry_key" expiration
|
371
|
+
# time (if applicable)
|
342
372
|
#
|
343
373
|
# @api private
|
344
374
|
def before_perform_retry(*args)
|
@@ -347,10 +377,15 @@ module Resque
|
|
347
377
|
|
348
378
|
# store number of retry attempts.
|
349
379
|
retry_key = redis_retry_key(*args)
|
350
|
-
Resque.redis.setnx(retry_key, -1)
|
351
|
-
@retry_attempt = Resque.redis.incr(retry_key)
|
380
|
+
Resque.redis.setnx(retry_key, -1)
|
381
|
+
@retry_attempt = Resque.redis.incr(retry_key)
|
352
382
|
log_message "attempt: #{@retry_attempt} set in Redis", args
|
353
|
-
|
383
|
+
|
384
|
+
# set/update the "retry_key" expiration
|
385
|
+
if expire_retry_key_after
|
386
|
+
log_message "updating expiration for retry key: #{retry_key}", args
|
387
|
+
Resque.redis.expire(retry_key, retry_delay + expire_retry_key_after)
|
388
|
+
end
|
354
389
|
end
|
355
390
|
|
356
391
|
# Resque after_perform hook
|
data/resque-retry.gemspec
CHANGED
@@ -30,7 +30,7 @@ Gem::Specification.new do |s|
|
|
30
30
|
s.require_paths = %w[lib]
|
31
31
|
|
32
32
|
s.add_dependency('resque', '~> 1.25')
|
33
|
-
s.add_dependency('resque-scheduler', '~>
|
33
|
+
s.add_dependency('resque-scheduler', '~> 3.0')
|
34
34
|
|
35
35
|
s.add_development_dependency('rake', '~> 10.1')
|
36
36
|
s.add_development_dependency('minitest', '~> 4.0')
|
data/test/retry_test.rb
CHANGED
@@ -55,12 +55,23 @@ class RetryTest < MiniTest::Unit::TestCase
|
|
55
55
|
assert_equal test_args, job['args']
|
56
56
|
end
|
57
57
|
|
58
|
-
def
|
59
|
-
Resque.enqueue(
|
58
|
+
def test_job_args_can_be_modified_by_overriding_args_for_retry
|
59
|
+
Resque.enqueue(DeprecatedRetryWithModifiedArgsJob)
|
60
|
+
DeprecatedRetryWithModifiedArgsJob.expects(:warn)
|
61
|
+
DeprecatedRetryWithModifiedArgsJob.expects(:args_for_retry)
|
60
62
|
perform_next_job(@worker)
|
63
|
+
end
|
61
64
|
|
62
|
-
|
63
|
-
|
65
|
+
def test_job_args_can_be_modified_by_overriding_retry_args
|
66
|
+
Resque.enqueue(RetryWithModifiedArgsJob)
|
67
|
+
RetryWithModifiedArgsJob.expects(:retry_args)
|
68
|
+
perform_next_job(@worker)
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_job_args_can_be_modified_by_overriding_retry_args_for_exception
|
72
|
+
Resque.enqueue(RetryWithExceptionBasedArgsJob)
|
73
|
+
RetryWithExceptionBasedArgsJob.expects(:retry_args_for_exception)
|
74
|
+
perform_next_job(@worker)
|
64
75
|
end
|
65
76
|
|
66
77
|
def test_retry_never_give_up
|
@@ -286,22 +297,19 @@ class RetryTest < MiniTest::Unit::TestCase
|
|
286
297
|
perform_next_job(@worker)
|
287
298
|
end
|
288
299
|
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
end
|
299
|
-
Process.waitpid(child)
|
300
|
-
job.fail(Resque::DirtyExit.new)
|
301
|
-
end
|
300
|
+
def test_expire_key_setting_on_the_fly
|
301
|
+
retry_key = 'resque-retry:FailFiveTimesWithCustomExpiryJob'
|
302
|
+
|
303
|
+
Resque.redis.expects(:expire).
|
304
|
+
with(retry_key, 100).then.
|
305
|
+
with(retry_key, 101).then.
|
306
|
+
with(retry_key, 102).then.
|
307
|
+
with(retry_key, 103).then.
|
308
|
+
with(retry_key, 104)
|
302
309
|
|
303
|
-
|
310
|
+
Resque.enqueue(FailFiveTimesWithCustomExpiryJob)
|
311
|
+
5.times do
|
312
|
+
perform_next_job(@worker)
|
304
313
|
end
|
305
314
|
end
|
306
|
-
|
307
315
|
end
|
data/test/test_jobs.rb
CHANGED
@@ -41,7 +41,7 @@ class RetryDefaultsJob
|
|
41
41
|
@queue = :testing
|
42
42
|
|
43
43
|
def self.perform(*args)
|
44
|
-
raise
|
44
|
+
raise 'error'
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
@@ -102,11 +102,27 @@ class InheritTestWithMoreExtraJob < InheritTestWithExtraJob
|
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
|
-
class
|
105
|
+
class DeprecatedRetryWithModifiedArgsJob < RetryDefaultsJob
|
106
106
|
@queue = :testing
|
107
107
|
|
108
108
|
def self.args_for_retry(*args)
|
109
|
-
|
109
|
+
# NOTE: implementation is irrelevant we only care that it's invoked
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
class RetryWithModifiedArgsJob < RetryDefaultsJob
|
114
|
+
@queue = :testing
|
115
|
+
|
116
|
+
def self.retry_args(*args)
|
117
|
+
# NOTE: implementation is irrelevant we only care that it's invoked
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
class RetryWithExceptionBasedArgsJob < RetryDefaultsJob
|
122
|
+
@queue = :testing
|
123
|
+
|
124
|
+
def self.retry_args_for_exception(exception, *args)
|
125
|
+
# NOTE: implementation is irrelevant we only care that it's invoked
|
110
126
|
end
|
111
127
|
end
|
112
128
|
|
@@ -154,6 +170,19 @@ class FailFiveTimesWithExpiryJob < RetryDefaultsJob
|
|
154
170
|
end
|
155
171
|
end
|
156
172
|
|
173
|
+
class FailFiveTimesWithCustomExpiryJob < RetryDefaultsJob
|
174
|
+
@queue = :testing
|
175
|
+
@retry_limit = 6
|
176
|
+
|
177
|
+
def self.expire_retry_key_after
|
178
|
+
retry_attempt + 100
|
179
|
+
end
|
180
|
+
|
181
|
+
def self.perform(*args)
|
182
|
+
raise if retry_attempt <= 4
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
157
186
|
class ExponentialBackoffJob < RetryDefaultsJob
|
158
187
|
extend Resque::Plugins::ExponentialBackoff
|
159
188
|
@queue = :testing
|
@@ -474,13 +503,3 @@ class FailsDuringConnectJob < RetryDefaultsJob
|
|
474
503
|
@retry_limit = 3
|
475
504
|
@retry_delay = 10
|
476
505
|
end
|
477
|
-
|
478
|
-
|
479
|
-
class RetryKilledJob
|
480
|
-
extend Resque::Plugins::Retry
|
481
|
-
@queue = :testing
|
482
|
-
|
483
|
-
def self.perform(*args)
|
484
|
-
Process.kill("KILL", Process.pid)
|
485
|
-
end
|
486
|
-
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.
|
4
|
+
version: 1.3.0
|
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: 2014-
|
13
|
+
date: 2014-07-25 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: resque
|
@@ -32,14 +32,14 @@ dependencies:
|
|
32
32
|
requirements:
|
33
33
|
- - "~>"
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: '
|
35
|
+
version: '3.0'
|
36
36
|
type: :runtime
|
37
37
|
prerelease: false
|
38
38
|
version_requirements: !ruby/object:Gem::Requirement
|
39
39
|
requirements:
|
40
40
|
- - "~>"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: '
|
42
|
+
version: '3.0'
|
43
43
|
- !ruby/object:Gem::Dependency
|
44
44
|
name: rake
|
45
45
|
requirement: !ruby/object:Gem::Requirement
|