Skip to content

Commit 427bc30

Browse files
authored
0.8.0 - Priority#to_f, plus some regression coverage (#54)
I'm adding regression coverage for the changes made in #53, and making one additional change in line with the way that the `:perform` callback [works in the `delayed_job` gem](https://github.com/collectiveidea/delayed_job/blob/ea4879dd3c2f3f5aa7f616a6f0fd58f2bbc2a481/lib/delayed/worker.rb#L313) - there is also now a test that will more explicitly check the order of callback events and behavior on job failure. Plus, while debugging in an app, I noticed that datadog tries to cast priority to a float, which was raising a method undefined error. So I added `Delayed::Priority#to_f` and added a test to cover all the explicit conversion methods (`to_s`, `to_i`, `to_f`, `to_d`).
1 parent 2ea5f07 commit 427bc30

6 files changed

Lines changed: 50 additions & 12 deletions

File tree

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PATH
22
remote: .
33
specs:
4-
delayed (0.7.2)
4+
delayed (0.8.0)
55
activerecord (>= 5.2)
66
concurrent-ruby
77

delayed.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
1818
spec.require_paths = ['lib']
1919
spec.summary = 'a multi-threaded, SQL-driven ActiveJob backend used at Betterment to process millions of background jobs per day'
2020

21-
spec.version = '0.7.2'
21+
spec.version = '0.8.0'
2222
spec.metadata = {
2323
'changelog_uri' => 'https://github.com/betterment/delayed/blob/main/CHANGELOG.md',
2424
'bug_tracker_uri' => 'https://github.com/betterment/delayed/issues',

lib/delayed/priority.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ def method_missing(method_name, *args)
140140
attr_reader :value
141141

142142
delegate :to_i, to: :value
143+
delegate :to_f, to: :value
143144
delegate :to_s, to: :name
144145

145146
def initialize(value)

lib/delayed/worker.rb

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -142,17 +142,17 @@ def perform(job)
142142
job.destroy
143143
end
144144
job_say job, format('COMPLETED after %.4f seconds', run_time)
145+
true # did work
146+
rescue DeserializationError => e
147+
job_say job, "FAILED permanently with #{e.class.name}: #{e.message}", 'error'
148+
149+
job.error = e
150+
failed(job)
151+
false # work failed
152+
rescue Exception => e # rubocop:disable Lint/RescueException
153+
self.class.lifecycle.run_callbacks(:error, self, job) { handle_failed_job(job, e) }
154+
false # work failed
145155
end
146-
true # did work
147-
rescue DeserializationError => e
148-
job_say job, "FAILED permanently with #{e.class.name}: #{e.message}", 'error'
149-
150-
job.error = e
151-
failed(job)
152-
false # work failed
153-
rescue Exception => e # rubocop:disable Lint/RescueException
154-
self.class.lifecycle.run_callbacks(:error, self, job) { handle_failed_job(job, e) }
155-
false # work failed
156156
end
157157

158158
# Reschedule the job in the future (when a job fails).

spec/delayed/priority_spec.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,13 @@
207207
expect(described_class.new(101)).to eq described_class.new(101) # rubocop:disable RSpec/IdenticalEqualityAssertion
208208
end
209209

210+
it 'supports explicit casting' do
211+
expect(described_class.new(0).to_i).to eq 0
212+
expect(described_class.new(3).to_f).to eq 3.0
213+
expect(described_class.new(10).to_s).to eq 'user_visible'
214+
expect(described_class.new(:eventual).to_d).to eq '20'.to_d
215+
end
216+
210217
it 'suports coercion' do
211218
expect(described_class.new(0)).to eq 0
212219
expect(described_class.new(8)).to be > 5

spec/worker_spec.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,5 +239,35 @@
239239

240240
expect(performances.value).to eq(1)
241241
end
242+
243+
it 'wraps perform and cleanup, even when perform raises' do
244+
events = []
245+
last_error = nil
246+
247+
plugin = Class.new(Delayed::Plugin) do
248+
callbacks do |lifecycle|
249+
lifecycle.around(:thread) do |_, &blk|
250+
events << :thread_start
251+
blk.call
252+
events << :thread_end
253+
end
254+
lifecycle.around(:perform) do |_, job, &blk|
255+
events << :perform_start
256+
blk.call.tap do
257+
last_error = job.last_error
258+
events << :perform_end
259+
end
260+
end
261+
end
262+
end
263+
264+
Delayed.plugins << plugin
265+
266+
Delayed::Job.enqueue ErrorJob.new
267+
described_class.new.work_off
268+
269+
expect(events).to eq %i(thread_start perform_start perform_end thread_end)
270+
expect(last_error).to match(/did not work/) # assert that cleanup happened before `:perform_end`
271+
end
242272
end
243273
end

0 commit comments

Comments
 (0)