resque-retry 1.7.3 → 1.7.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 215fb485738158bbc70e52dc3cfb8ffe0f506cea4eea5000c63bfd0112e1e1ad
4
- data.tar.gz: d3de2dc53f2d491ef38327723c72fe0fe393caeb611887037128345f1a782a36
3
+ metadata.gz: ab175830aa9de0d24e514a8bd054b1ebe8a2924ba134fd975013685e84828b9d
4
+ data.tar.gz: a6cb49fb45375e4a82a8811e126f428de4acda1248d7b6cc6de5df6d9b6340bf
5
5
  SHA512:
6
- metadata.gz: d3e70d04e8248d787febc0fa2abbf1b2d61b29daca52eb43348beafda614acd0498bd93fd52a3b53f10d9010e1d2f180a7689ca0a36a4b2aada5478105140774
7
- data.tar.gz: 1756af428ee66d0538fc8c428929408098add0f820506881fe295022069465ae624d96263dbaf6dff154c15711e1dd57a54363c927a3f2a240ff7e118f6f356b
6
+ metadata.gz: f4176df779bbc212e25d64190ae7680ee410beebb663d6b502f45fd73532b14fa4ed9f86dc76e74474dd757247b45b0a8503037a6154c814ffad159dec22413a
7
+ data.tar.gz: 2109a5558025ff2d7b5b8e1cd952242aad11641b11b1036332d2f68111c1d6ca5f9de402ec92376aedff37d6dff534bed0e017196e85f451b976e405168a71da
data/HISTORY.md CHANGED
@@ -1,3 +1,8 @@
1
+ # 1.7.4 (2020-10-09)
2
+
3
+ * Rework how the default `retry_limit` is calculated
4
+ * Numerous documentation updates
5
+
1
6
  # 1.7.3 (2019-11-21)
2
7
 
3
8
  * Do not crash if job class is not found on the resque-web server
data/README.md CHANGED
@@ -231,8 +231,8 @@ class ExampleJob
231
231
  extend Resque::Plugins::Retry
232
232
  @queue = :testing
233
233
 
234
- def self.retry_delay(exception)
235
- if exception == SocketError
234
+ def self.retry_delay(exception_class)
235
+ if exception_class == SocketError
236
236
  10
237
237
  else
238
238
  1
@@ -359,7 +359,12 @@ You may also want to specify different retry delays for different exception
359
359
  types. You may optionally set `@retry_exceptions` to a hash where the keys are
360
360
  your specific exception classes to retry on, and the values are your retry
361
361
  delays in seconds or an array of retry delays to be used similar to exponential
362
- backoff.
362
+ backoff. `resque-retry` will attempt to determine your retry strategy's
363
+ `@retry_limit` based on your specified `@retry_exceptions`. If, however, you
364
+ define `@retry_limit` explicitly, you should define `@retry_limit` such that it
365
+ allows for your retry strategies to complete. If your `@retry_limit` is less
366
+ than the number of desired retry attempts defined in `@retry_exceptions`, your
367
+ job will only retry `@retry_limit` times.
363
368
  ```ruby
364
369
  class DeliverSMS
365
370
  extend Resque::Plugins::Retry
@@ -374,9 +379,15 @@ end
374
379
  ```
375
380
 
376
381
  In the above example, Resque would retry any `DeliverSMS` jobs which throw a
377
- `NetworkError` or `SystemCallError`. If the job throws a `NetworkError` it
378
- will be retried 30 seconds later, if it throws `SystemCallError` it will first
379
- retry 120 seconds later then subsequent retry attempts 240 seconds later.
382
+ `NetworkError` or `SystemCallError`. The `@retry_limit` would be inferred to be
383
+ 2 based on the longest retry strategy defined in `@retry_exceptions`. If the job
384
+ throws a `NetworkError` it will be retried 30 seconds later with a subsequent
385
+ retry 30 seconds after that. If it throws a `SystemCallError` it will first
386
+ retry 120 seconds later then a subsequent retry attempt 240 seconds later. If
387
+ the job fails due to a `NetworkError`, Resque would retry the job in 30 seconds.
388
+ If the job fails a second time, this time due to a `SystemCallError`, the next
389
+ retry would occur 240 seconds later as specified in the `SystemCallError`
390
+ array defined in `@retry_exceptions`.
380
391
 
381
392
  ### <a name="fail_fast"></a> Fail Fast For Specific Exceptions
382
393
 
@@ -511,7 +522,7 @@ class ExampleJob
511
522
 
512
523
  def self.work(*args)
513
524
  user_id, user_mode, record_id = *args
514
-
525
+
515
526
  Resque.enqueue_to(
516
527
  target_queue_for_args(user_id, user_mode, record_id),
517
528
  self,
@@ -531,7 +542,7 @@ class ExampleJob
531
542
  user_id, user_mode, record_id = *args
532
543
 
533
544
  if user_mode
534
- 'high
545
+ 'high'
535
546
  else
536
547
  'low'
537
548
  end
@@ -585,7 +596,7 @@ end
585
596
 
586
597
  This saves you from having to run a "house cleaning" or "errand" job.
587
598
 
588
- The expiary timeout is "pushed forward" or "touched" after each failure to
599
+ The expiry timeout is "pushed forward" or "touched" after each failure to
589
600
  ensure it's not expired too soon.
590
601
 
591
602
  ### <a name="callbacks"></a> Try Again and Give Up Callbacks
@@ -1,3 +1,3 @@
1
1
  module ResqueRetry
2
- VERSION = '1.7.3'
2
+ VERSION = '1.7.4'
3
3
  end
@@ -80,10 +80,11 @@ module Resque
80
80
 
81
81
  # Selects the delay from the backoff strategy
82
82
  #
83
+ # @param _ [Exception] unused exception argument for signature parity
83
84
  # @return [Number] seconds to delay until the next retry.
84
85
  #
85
86
  # @api private
86
- def retry_delay
87
+ def retry_delay(_ = nil)
87
88
  delay = backoff_strategy[retry_attempt] || backoff_strategy.last
88
89
  # if the values are the same don't bother generating a random number, if
89
90
  # the delta is zero, some platforms will raise an error
@@ -107,11 +107,27 @@ module Resque
107
107
  # A retry limit of 0 will *never* retry.
108
108
  # A retry limit of -1 or below will retry forever.
109
109
  #
110
+ # The default value is: `1` or in the case of where `@retry_exceptions` is
111
+ # specified, and it contains one or more `Array` values, the maximum
112
+ # length will be used (e.g. `@retry_exceptions = { NetworkError => 30, SystemCallError => [120, 240] }`
113
+ # would return `2` because `SystemCallError` _should_ be attempted at
114
+ # least twice to respect the specified configuration).
115
+ #
110
116
  # @return [Fixnum]
111
117
  #
112
118
  # @api public
113
119
  def retry_limit
114
- @retry_limit ||= 1
120
+ @retry_limit ||= begin
121
+ default_retry_limit = 1
122
+ if instance_variable_defined?(:@retry_exceptions) && @retry_exceptions.is_a?(Hash)
123
+ @retry_exceptions.values.each do |value|
124
+ if value.is_a?(Array) && value.length > default_retry_limit
125
+ default_retry_limit = value.length
126
+ end
127
+ end
128
+ end
129
+ default_retry_limit
130
+ end
115
131
  end
116
132
 
117
133
  # Number of retry attempts used to try and perform the job
@@ -128,4 +128,11 @@ class ExponentialBackoffTest < Minitest::Test
128
128
  assert_equal 4, Resque.info[:failed], 'failed jobs'
129
129
  assert_equal 0, Resque.info[:pending], 'pending jobs'
130
130
  end
131
+
132
+ def test_backoff_with_expiration
133
+ Resque.redis.expects(:expire)
134
+
135
+ Resque.enqueue(ExponentialBackoffWithExpiryJob)
136
+ perform_next_job(@worker)
137
+ end
131
138
  end
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class RetryExeptionDelayTest < Minitest::Test
3
+ class RetryExceptionDelayTest < Minitest::Test
4
4
  def setup
5
5
  Resque.redis.flushall
6
6
  @worker = Resque::Worker.new(:testing)
@@ -43,4 +43,12 @@ class RetryExeptionDelayTest < Minitest::Test
43
43
  assert_in_delta (start_time + 10), delayed[1], 1.00, '2nd retry delay timestamp'
44
44
  assert_in_delta (start_time + 15), delayed[2], 1.00, '3rd retry delay timestamp'
45
45
  end
46
+
47
+ def test_retry_delay_per_exception_multiple_delay_no_retry_limit_specified
48
+ # For this job-type there are 3 `Exception` types defined: `Exception`,
49
+ # `StandardError` and `Timeout::Error` -- their array-lengths are are 1, 3
50
+ # and 5 (respectively). We expect the `retry_limit` to default to the
51
+ # maximum length of the `Array` of delays or 1 (in this case: 5)
52
+ assert_equal 5, PerExceptionClassRetryCountArrayNoRetryLimitSpecifiedJob.retry_limit
53
+ end
46
54
  end
@@ -254,6 +254,12 @@ class ExponentialBackoffWithRetryDelayMultiplicandMinAndMaxJob < RetryDefaultsJo
254
254
  @retry_delay_multiplicand_max = 3.0
255
255
  end
256
256
 
257
+ class ExponentialBackoffWithExpiryJob < RetryDefaultsJob
258
+ extend Resque::Plugins::ExponentialBackoff
259
+ @queue = :testing
260
+ @expire_retry_key_after = 60 * 60
261
+ end
262
+
257
263
  class InvalidRetryDelayMaxConfigurationJob
258
264
  @queue = :testing
259
265
  @retry_delay_multiplicand_max = 0.9
@@ -576,6 +582,17 @@ class PerExceptionClassRetryCountArrayJob
576
582
  end
577
583
  end
578
584
 
585
+ class PerExceptionClassRetryCountArrayNoRetryLimitSpecifiedJob
586
+ extend Resque::Plugins::Retry
587
+
588
+ @queue = :testing
589
+ @retry_exceptions = { Exception => 11, RuntimeError => [5, 10, 15], Timeout::Error => [2, 4, 6, 8, 10] }
590
+
591
+ def self.perform
592
+ raise RuntimeError, 'I always fail with a RuntimeError'
593
+ end
594
+ end
595
+
579
596
  # We can't design a job to fail during connect, see perform_next_job_fail_on_reconnect
580
597
  class FailsDuringConnectJob < RetryDefaultsJob
581
598
  @queue = :testing
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: resque-retry
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.3
4
+ version: 1.7.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luke Antins
8
8
  - Ryan Carver
9
9
  - Jonathan W. Zaleski
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2019-11-21 00:00:00.000000000 Z
13
+ date: 2020-10-09 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: resque
@@ -208,7 +208,7 @@ homepage: http://github.com/lantins/resque-retry
208
208
  licenses:
209
209
  - MIT
210
210
  metadata: {}
211
- post_install_message:
211
+ post_install_message:
212
212
  rdoc_options: []
213
213
  require_paths:
214
214
  - lib
@@ -223,8 +223,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
223
223
  - !ruby/object:Gem::Version
224
224
  version: '0'
225
225
  requirements: []
226
- rubygems_version: 3.0.6
227
- signing_key:
226
+ rubygems_version: 3.1.4
227
+ signing_key:
228
228
  specification_version: 4
229
229
  summary: A resque plugin; provides retry, delay and exponential backoff support for
230
230
  resque jobs.