inst-jobs 2.0.0 → 2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d674b7da21caf04eb87ff9823ed549c93a901219669316090d088f0699564e59
4
- data.tar.gz: 021456d34f12eff8cc988db866018d701fc77ffdbb57e9fb308fc1bd25a91ecb
3
+ metadata.gz: b789a390da84dd32ede51b6d8655853e3f20efa55144fe19cf0605d9e5083e62
4
+ data.tar.gz: bd263366443698e93572f83a6f0e2b3d747c9e72acd851fbc0aa3f920c413e02
5
5
  SHA512:
6
- metadata.gz: ad78cfdd9026db24b714c532c8ee837a875e443afc375909f0c130e3cfbf87d1f872344f982d931838bfa6649a2f1edc59430f6444a2baee08f8afb568015cfc
7
- data.tar.gz: e2b127477f0687958178505628b9544aa5c49e7aa1d0ceef32892250aa26aeb1c77f12bcacd6682e17c2bc379f987b154a0f982e029852432c39f7b3a5335df8
6
+ metadata.gz: b902bbdb3d4d676b984a22c2df5d4382960219de7a9a3d639df4fd6f958816ac77a3e2e00e881d7afbc240fd6043eef21f5362885301ccf1c9fb1ae790a21e2f
7
+ data.tar.gz: 3dbb3fe818c20be76f6f07f61893014bc881a2f82a7c44139e62642230ff49a2acd0d3e2ba746b4bcdf1834fed0b5cb1ebcbb6ea3431b9fe46ffc29d6956200b
@@ -178,6 +178,10 @@ module Delayed
178
178
  expires_at && (self.class.db_time_now >= expires_at)
179
179
  end
180
180
 
181
+ def inferred_max_attempts
182
+ self.max_attempts || Delayed::Settings.max_attempts
183
+ end
184
+
181
185
  # Reschedule the job in the future (when a job fails).
182
186
  # Uses an exponential scale depending on the number of failed attempts.
183
187
  def reschedule(error = nil, time = nil)
@@ -190,7 +194,7 @@ module Delayed
190
194
 
191
195
  self.attempts += 1 unless return_code == :unlock
192
196
 
193
- if self.attempts >= (self.max_attempts || Delayed::Settings.max_attempts)
197
+ if self.attempts >= self.inferred_max_attempts
194
198
  permanent_failure error || "max attempts reached"
195
199
  elsif expired?
196
200
  permanent_failure error || "job has expired"
@@ -12,6 +12,7 @@ module Delayed
12
12
  :loop => [:worker],
13
13
  :perform => [:worker, :job],
14
14
  :pop => [:worker],
15
+ :retry => [:worker, :job, :exception],
15
16
  :work_queue_pop => [:work_queue, :worker_config],
16
17
  :check_for_work => [:work_queue],
17
18
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Delayed
4
- VERSION = "2.0.0"
4
+ VERSION = "2.1.0"
5
5
  end
@@ -3,6 +3,17 @@
3
3
  module Delayed
4
4
 
5
5
  class TimeoutError < RuntimeError; end
6
+ class RetriableError < RuntimeError
7
+ # this error is a special case. You _should_ raise
8
+ # it from inside the rescue block for another error,
9
+ # because it indicates: "something made this job fail
10
+ # but we're pretty sure it's transient and it's safe to try again".
11
+ # the workflow is still the same (retry will happen unless
12
+ # retries are exhausted), but it won't call the :error
13
+ # callback unless it can't retry anymore. It WILL call the
14
+ # separate ":retry" callback, which is ONLY activated
15
+ # for this kind of error.
16
+ end
6
17
 
7
18
  require 'tmpdir'
8
19
  require 'set'
@@ -216,6 +227,12 @@ class Worker
216
227
  logger.info("Completed #{log_job(job)} #{"%.0fms" % (runtime * 1000)}")
217
228
  end
218
229
  count
230
+ rescue ::Delayed::RetriableError => re
231
+ can_retry = job.attempts + 1 < job.inferred_max_attempts
232
+ callback_type = can_retry ? :retry : :error
233
+ self.class.lifecycle.run_callbacks(callback_type, self, job, re) do
234
+ handle_failed_job(job, re)
235
+ end
219
236
  rescue SystemExit => se
220
237
  # There wasn't really a failure here so no callbacks and whatnot needed,
221
238
  # still reschedule the job though.
@@ -19,6 +19,19 @@ describe Delayed::Worker do
19
19
  expect(fired).to be_truthy
20
20
  end
21
21
 
22
+ it "uses the retry callback for a retriable exception" do
23
+ error_fired = retry_fired = false
24
+ Delayed::Worker.lifecycle.before(:error) {|worker, exception| error_fired = true }
25
+ Delayed::Worker.lifecycle.before(:retry) {|worker, exception| retry_fired = true}
26
+ job = Delayed::Job.new(payload_object: {}, priority: 25, strand: "test_jobs", max_attempts: 3)
27
+ expect(job).to receive(:invoke_job) do
28
+ raise Delayed::RetriableError, "that's all this job does"
29
+ end
30
+ subject.perform(job)
31
+ expect(error_fired).to be_falsey
32
+ expect(retry_fired).to be_truthy
33
+ end
34
+
22
35
  it "reloads" do
23
36
  fakeApplication = double('Rails.application',
24
37
  config: double('Rails.application.config',
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inst-jobs
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Luetke