delayed 0.7.1 → 0.8.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/lib/delayed/priority.rb +1 -0
- data/lib/delayed/worker.rb +18 -21
- data/lib/delayed.rb +1 -1
- data/spec/delayed/job_spec.rb +4 -4
- data/spec/delayed/priority_spec.rb +7 -0
- data/spec/worker_spec.rb +30 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6268c514bb90e5279b8265c4ce21eea8262ac4d539ff161c7f9eab12f15f17ba
|
4
|
+
data.tar.gz: eb0c1f81475163766a680eab603740a4632956fb415e4158430a67bb3998c381
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 73686b95d83b336dcf268f4524fb8b512e64f61b58773b0884e8f1a4c30abc89532aaa0df4e1395d69417d2062ae7e948157c7cd5b3b7cb80982c68dbf798936
|
7
|
+
data.tar.gz: 9f3b7437e5772e0fe44b3f168cd32b78073b6c49b2fc208b713d946d4b48f14549646363856e3d62a7525059a7d841fbe0191a520af3dc06a71e3d258679b68e
|
data/lib/delayed/priority.rb
CHANGED
data/lib/delayed/worker.rb
CHANGED
@@ -101,7 +101,12 @@ module Delayed
|
|
101
101
|
pool = Concurrent::FixedThreadPool.new(jobs.length)
|
102
102
|
jobs.each do |job|
|
103
103
|
pool.post do
|
104
|
-
|
104
|
+
self.class.lifecycle.run_callbacks(:thread, self, job) do
|
105
|
+
success.increment if perform(job)
|
106
|
+
end
|
107
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
108
|
+
job_say job, "Job thread crashed with #{e.class.name}: #{e.message}", 'error'
|
109
|
+
job.error = e
|
105
110
|
end
|
106
111
|
end
|
107
112
|
|
@@ -117,12 +122,8 @@ module Delayed
|
|
117
122
|
[success.value, total - success.value]
|
118
123
|
end
|
119
124
|
|
120
|
-
def
|
121
|
-
self.class.lifecycle.run_callbacks(:
|
122
|
-
end
|
123
|
-
|
124
|
-
def run(job)
|
125
|
-
run_thread_callbacks(job) do
|
125
|
+
def perform(job)
|
126
|
+
self.class.lifecycle.run_callbacks(:perform, self, job) do
|
126
127
|
metadata = {
|
127
128
|
status: 'RUNNING',
|
128
129
|
name: job.name,
|
@@ -141,17 +142,17 @@ module Delayed
|
|
141
142
|
job.destroy
|
142
143
|
end
|
143
144
|
job_say job, format('COMPLETED after %.4f seconds', run_time)
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
job_say job, "FAILED permanently with #{e.class.name}: #{e.message}", 'error'
|
145
|
+
true # did work
|
146
|
+
rescue DeserializationError => e
|
147
|
+
job_say job, "FAILED permanently with #{e.class.name}: #{e.message}", 'error'
|
148
148
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
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
|
155
|
+
end
|
155
156
|
end
|
156
157
|
|
157
158
|
# Reschedule the job in the future (when a job fails).
|
@@ -209,10 +210,6 @@ module Delayed
|
|
209
210
|
reschedule(job)
|
210
211
|
end
|
211
212
|
|
212
|
-
def run_job(job)
|
213
|
-
self.class.lifecycle.run_callbacks(:perform, self, job) { run(job) }
|
214
|
-
end
|
215
|
-
|
216
213
|
# The backend adapter may return either a list or a single job
|
217
214
|
# In some backends, this can be controlled with the `max_claims` config
|
218
215
|
# Either way, we map this to an array of job instances
|
data/lib/delayed.rb
CHANGED
data/spec/delayed/job_spec.rb
CHANGED
@@ -533,7 +533,7 @@ describe Delayed::Job do
|
|
533
533
|
it 'fails after Worker.max_run_time' do
|
534
534
|
Delayed::Worker.max_run_time = 1.second
|
535
535
|
job = described_class.create payload_object: LongRunningJob.new
|
536
|
-
worker.
|
536
|
+
worker.perform(job)
|
537
537
|
expect(job.error).not_to be_nil
|
538
538
|
expect(job.reload.last_error).to match(/expired/)
|
539
539
|
expect(job.reload.last_error).to match(/Delayed::Worker\.max_run_time is only 1 second/)
|
@@ -558,7 +558,7 @@ describe Delayed::Job do
|
|
558
558
|
|
559
559
|
it 'records last_error when destroy_failed_jobs = false, max_attempts = 1' do
|
560
560
|
Delayed::Worker.max_attempts = 1
|
561
|
-
worker.
|
561
|
+
worker.perform(@job)
|
562
562
|
@job.reload
|
563
563
|
expect(@job.error).not_to be_nil
|
564
564
|
expect(@job.last_error).to match(/did not work/)
|
@@ -580,7 +580,7 @@ describe Delayed::Job do
|
|
580
580
|
|
581
581
|
it 're-schedules jobs with handler provided time if present' do
|
582
582
|
job = described_class.enqueue(CustomRescheduleJob.new(99.minutes))
|
583
|
-
worker.
|
583
|
+
worker.perform(job)
|
584
584
|
job.reload
|
585
585
|
|
586
586
|
expect((described_class.db_time_now + 99.minutes - job.run_at).abs).to be < 1
|
@@ -590,7 +590,7 @@ describe Delayed::Job do
|
|
590
590
|
error_with_nil_message = StandardError.new
|
591
591
|
expect(error_with_nil_message).to receive(:message).twice.and_return(nil)
|
592
592
|
expect(@job).to receive(:invoke_job).and_raise error_with_nil_message
|
593
|
-
expect { worker.
|
593
|
+
expect { worker.perform(@job) }.not_to raise_error
|
594
594
|
end
|
595
595
|
end
|
596
596
|
|
@@ -207,6 +207,13 @@ RSpec.describe Delayed::Priority do
|
|
207
207
|
expect(described_class.new(101)).to eq described_class.new(101) # rubocop:disable RSpec/IdenticalEqualityAssertion
|
208
208
|
end
|
209
209
|
|
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
|
+
|
210
217
|
it 'suports coercion' do
|
211
218
|
expect(described_class.new(0)).to eq 0
|
212
219
|
expect(described_class.new(8)).to be > 5
|
data/spec/worker_spec.rb
CHANGED
@@ -239,5 +239,35 @@ describe Delayed::Worker do
|
|
239
239
|
|
240
240
|
expect(performances.value).to eq(1)
|
241
241
|
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
|
242
272
|
end
|
243
273
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: delayed
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Griffith
|
@@ -18,7 +18,7 @@ authors:
|
|
18
18
|
- Tobias Lütke
|
19
19
|
bindir: bin
|
20
20
|
cert_chain: []
|
21
|
-
date: 2025-
|
21
|
+
date: 2025-04-03 00:00:00.000000000 Z
|
22
22
|
dependencies:
|
23
23
|
- !ruby/object:Gem::Dependency
|
24
24
|
name: activerecord
|
@@ -137,7 +137,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
139
|
requirements: []
|
140
|
-
rubygems_version: 3.6.
|
140
|
+
rubygems_version: 3.6.6
|
141
141
|
specification_version: 4
|
142
142
|
summary: a multi-threaded, SQL-driven ActiveJob backend used at Betterment to process
|
143
143
|
millions of background jobs per day
|