delayed 0.5.3 → 0.5.4
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/README.md +8 -0
- data/lib/delayed/active_job_adapter.rb +10 -0
- data/lib/delayed/priority.rb +44 -4
- data/spec/delayed/active_job_adapter_spec.rb +13 -0
- data/spec/delayed/priority_spec.rb +85 -1
- metadata +17 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e76902c89ee215794e6c6b987b69a9c00371fd70658a3ef1accd7751587b17a5
|
4
|
+
data.tar.gz: d4e2ddc68375700e839e60aadb487bbeacf55f603d392ec0a11099429685ae77
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6240ae94bee15f2f434e6a73941ad3123add526ac29b56a13127aa7797fbf006dd8e1f73b6a53b533b9494d6d99b4f30550fd3d632eadc5b4cbb2c2a4dbd796c
|
7
|
+
data.tar.gz: d0fef6960b1e32f400f53779886e0465c4c7fcf8d66b30de17c588c17a2661c66391dc3ba978a67890d21799980fff22195881eb30eaef7bdfabd4049c8a21ee
|
data/README.md
CHANGED
@@ -491,6 +491,14 @@ Delayed::Worker.min_priority = nil
|
|
491
491
|
Delayed::Worker.max_priority = nil
|
492
492
|
```
|
493
493
|
|
494
|
+
Job priorities can specified by using the name of the desired range (i.e. :user_visible).
|
495
|
+
By default, the value for a named priority will be the first value in that range.
|
496
|
+
To set each priority's default value to the middle of its range (i.e. 15 for :user_visible), Delayed::Priority can be configured with:
|
497
|
+
|
498
|
+
```ruby
|
499
|
+
Delayed::Priority.assign_at_midpoint = true
|
500
|
+
```
|
501
|
+
|
494
502
|
Logging verbosity is also configurable. The gem will attempt to default to `Rails.logger` with an
|
495
503
|
"info" log level.
|
496
504
|
|
@@ -1,5 +1,11 @@
|
|
1
1
|
module Delayed
|
2
2
|
class ActiveJobAdapter
|
3
|
+
class UnsafeEnqueueError < RuntimeError; end
|
4
|
+
|
5
|
+
def enqueue_after_transaction_commit?
|
6
|
+
false
|
7
|
+
end
|
8
|
+
|
3
9
|
def enqueue(job)
|
4
10
|
_enqueue(job)
|
5
11
|
end
|
@@ -11,6 +17,10 @@ module Delayed
|
|
11
17
|
private
|
12
18
|
|
13
19
|
def _enqueue(job, opts = {})
|
20
|
+
if job.class.respond_to?(:enqueue_after_transaction_commit) && job.class.enqueue_after_transaction_commit
|
21
|
+
raise UnsafeEnqueueError, "The ':delayed' ActiveJob adapter is not compatible with enqueue_after_transaction_commit"
|
22
|
+
end
|
23
|
+
|
14
24
|
opts.merge!({ queue: job.queue_name, priority: job.priority }.compact)
|
15
25
|
.merge!(job.provider_attributes || {})
|
16
26
|
|
data/lib/delayed/priority.rb
CHANGED
@@ -57,6 +57,8 @@ module Delayed
|
|
57
57
|
}.freeze
|
58
58
|
|
59
59
|
class << self
|
60
|
+
attr_writer :assign_at_midpoint
|
61
|
+
|
60
62
|
def names
|
61
63
|
@names || default_names
|
62
64
|
end
|
@@ -70,6 +72,7 @@ module Delayed
|
|
70
72
|
|
71
73
|
@ranges = nil
|
72
74
|
@alerts = nil
|
75
|
+
@names_to_priority = nil
|
73
76
|
@names = names&.sort_by(&:last)&.to_h&.transform_values { |v| new(v) }
|
74
77
|
end
|
75
78
|
|
@@ -82,12 +85,25 @@ module Delayed
|
|
82
85
|
@alerts = alerts&.sort_by { |k, _| names.keys.index(k) }&.to_h
|
83
86
|
end
|
84
87
|
|
88
|
+
def assign_at_midpoint?
|
89
|
+
@assign_at_midpoint || false
|
90
|
+
end
|
91
|
+
|
85
92
|
def ranges
|
86
93
|
@ranges ||= names.zip(names.except(names.keys.first)).each_with_object({}) do |((name, lower), (_, upper)), obj|
|
87
94
|
obj[name] = (lower...(upper || Float::INFINITY))
|
88
95
|
end
|
89
96
|
end
|
90
97
|
|
98
|
+
def names_to_priority
|
99
|
+
@names_to_priority ||=
|
100
|
+
if assign_at_midpoint?
|
101
|
+
names_to_midpoint_priority
|
102
|
+
else
|
103
|
+
names
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
91
107
|
private
|
92
108
|
|
93
109
|
def default_names
|
@@ -98,13 +114,23 @@ module Delayed
|
|
98
114
|
@names ? {} : DEFAULT_ALERTS
|
99
115
|
end
|
100
116
|
|
117
|
+
def names_to_midpoint_priority
|
118
|
+
names.each_cons(2).to_h { |(name, priority_value), (_, next_priority_value)|
|
119
|
+
[name, new(midpoint(priority_value, next_priority_value))]
|
120
|
+
}.merge(names.keys.last => new(names.values.last + 5))
|
121
|
+
end
|
122
|
+
|
123
|
+
def midpoint(low, high)
|
124
|
+
low + ((high - low).to_d / 2).ceil
|
125
|
+
end
|
126
|
+
|
101
127
|
def respond_to_missing?(method_name, include_private = false)
|
102
|
-
|
128
|
+
names_to_priority.key?(method_name) || super
|
103
129
|
end
|
104
130
|
|
105
131
|
def method_missing(method_name, *args)
|
106
|
-
if
|
107
|
-
|
132
|
+
if names_to_priority.key?(method_name) && args.none?
|
133
|
+
names_to_priority[method_name]
|
108
134
|
else
|
109
135
|
super
|
110
136
|
end
|
@@ -118,7 +144,7 @@ module Delayed
|
|
118
144
|
|
119
145
|
def initialize(value)
|
120
146
|
super()
|
121
|
-
value = self.class.
|
147
|
+
value = self.class.names_to_priority[value] if value.is_a?(Symbol)
|
122
148
|
@value = value.to_i
|
123
149
|
end
|
124
150
|
|
@@ -147,6 +173,20 @@ module Delayed
|
|
147
173
|
to_i <=> other
|
148
174
|
end
|
149
175
|
|
176
|
+
def -(other)
|
177
|
+
other = other.to_i if other.is_a?(self.class)
|
178
|
+
self.class.new(to_i - other)
|
179
|
+
end
|
180
|
+
|
181
|
+
def +(other)
|
182
|
+
other = other.to_i if other.is_a?(self.class)
|
183
|
+
self.class.new(to_i + other)
|
184
|
+
end
|
185
|
+
|
186
|
+
def to_d
|
187
|
+
to_i.to_d
|
188
|
+
end
|
189
|
+
|
150
190
|
private
|
151
191
|
|
152
192
|
def respond_to_missing?(method_name, include_private = false)
|
@@ -287,6 +287,19 @@ RSpec.describe Delayed::ActiveJobAdapter do
|
|
287
287
|
end
|
288
288
|
end
|
289
289
|
|
290
|
+
if ActiveJob.gem_version.release >= Gem::Version.new('7.2')
|
291
|
+
context 'when the given job sets enqueue_after_transaction_commit to true' do
|
292
|
+
before do
|
293
|
+
JobClass.include ActiveJob::EnqueueAfterTransactionCommit # normally run in an ActiveJob railtie
|
294
|
+
JobClass.enqueue_after_transaction_commit = true
|
295
|
+
end
|
296
|
+
|
297
|
+
it 'raises an exception on enqueue' do
|
298
|
+
expect { JobClass.perform_later }.to raise_error(Delayed::ActiveJobAdapter::UnsafeEnqueueError)
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
290
303
|
context 'when using the ActiveJob test adapter' do
|
291
304
|
let(:queue_adapter) { :test }
|
292
305
|
|
@@ -3,8 +3,10 @@ require 'helper'
|
|
3
3
|
RSpec.describe Delayed::Priority do
|
4
4
|
let(:custom_names) { nil }
|
5
5
|
let(:custom_alerts) { nil }
|
6
|
+
let(:assign_at_midpoint) { nil }
|
6
7
|
|
7
8
|
around do |example|
|
9
|
+
described_class.assign_at_midpoint = assign_at_midpoint
|
8
10
|
described_class.names = custom_names
|
9
11
|
described_class.alerts = custom_alerts
|
10
12
|
example.run
|
@@ -13,7 +15,7 @@ RSpec.describe Delayed::Priority do
|
|
13
15
|
described_class.names = nil
|
14
16
|
end
|
15
17
|
|
16
|
-
describe '.names, .ranges, .alerts, method_missing' do
|
18
|
+
describe '.names, .ranges, .alerts, .names_to_priority, method_missing' do
|
17
19
|
it 'defaults to interactive, user_visible, eventual, reporting' do
|
18
20
|
expect(described_class.names).to eq(
|
19
21
|
interactive: 0,
|
@@ -33,6 +35,12 @@ RSpec.describe Delayed::Priority do
|
|
33
35
|
eventual: { age: 1.5.hours, run_time: 5.minutes, attempts: 8 },
|
34
36
|
reporting: { age: 4.hours, run_time: 10.minutes, attempts: 8 },
|
35
37
|
)
|
38
|
+
expect(described_class.names_to_priority).to eq(
|
39
|
+
interactive: 0,
|
40
|
+
user_visible: 10,
|
41
|
+
eventual: 20,
|
42
|
+
reporting: 30,
|
43
|
+
)
|
36
44
|
expect(described_class).to respond_to(:interactive)
|
37
45
|
expect(described_class).to respond_to(:user_visible)
|
38
46
|
expect(described_class).to respond_to(:eventual)
|
@@ -43,6 +51,23 @@ RSpec.describe Delayed::Priority do
|
|
43
51
|
expect(described_class.reporting).to eq 30
|
44
52
|
end
|
45
53
|
|
54
|
+
context 'when assign_at_midpoint is set to true' do
|
55
|
+
let(:assign_at_midpoint) { true }
|
56
|
+
|
57
|
+
it 'returns the midpoint value' do
|
58
|
+
expect(described_class.names_to_priority).to eq(
|
59
|
+
interactive: 5,
|
60
|
+
user_visible: 15,
|
61
|
+
eventual: 25,
|
62
|
+
reporting: 35,
|
63
|
+
)
|
64
|
+
expect(described_class.interactive).to eq 5
|
65
|
+
expect(described_class.user_visible).to eq 15
|
66
|
+
expect(described_class.eventual).to eq 25
|
67
|
+
expect(described_class.reporting).to eq 35
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
46
71
|
context 'when customized to high, medium, low' do
|
47
72
|
let(:custom_names) { { high: 0, medium: 100, low: 500 } }
|
48
73
|
|
@@ -57,6 +82,11 @@ RSpec.describe Delayed::Priority do
|
|
57
82
|
medium: (100...500),
|
58
83
|
low: (500...Float::INFINITY),
|
59
84
|
)
|
85
|
+
expect(described_class.names_to_priority).to eq(
|
86
|
+
high: 0,
|
87
|
+
medium: 100,
|
88
|
+
low: 500,
|
89
|
+
)
|
60
90
|
expect(described_class.alerts).to eq({})
|
61
91
|
expect(described_class).not_to respond_to(:interactive)
|
62
92
|
expect(described_class).not_to respond_to(:user_visible)
|
@@ -81,6 +111,21 @@ RSpec.describe Delayed::Priority do
|
|
81
111
|
)
|
82
112
|
end
|
83
113
|
end
|
114
|
+
|
115
|
+
context 'when assign_at_midpoint is set to true' do
|
116
|
+
let(:assign_at_midpoint) { true }
|
117
|
+
|
118
|
+
it 'returns the midpoint value' do
|
119
|
+
expect(described_class.names_to_priority).to eq(
|
120
|
+
high: 50,
|
121
|
+
medium: 300,
|
122
|
+
low: 505,
|
123
|
+
)
|
124
|
+
expect(described_class.high).to eq 50
|
125
|
+
expect(described_class.medium).to eq 300
|
126
|
+
expect(described_class.low).to eq 505
|
127
|
+
end
|
128
|
+
end
|
84
129
|
end
|
85
130
|
end
|
86
131
|
|
@@ -110,6 +155,36 @@ RSpec.describe Delayed::Priority do
|
|
110
155
|
expect(described_class.new(-123).interactive?).to eq false
|
111
156
|
end
|
112
157
|
|
158
|
+
context 'when assign_at_midpoint is set to true' do
|
159
|
+
let(:assign_at_midpoint) { true }
|
160
|
+
|
161
|
+
it 'provides the name of the priority range' do
|
162
|
+
expect(described_class.new(0).name).to eq :interactive
|
163
|
+
expect(described_class.new(3).name).to eq :interactive
|
164
|
+
expect(described_class.new(10).name).to eq :user_visible
|
165
|
+
expect(described_class.new(29).name).to eq :eventual
|
166
|
+
expect(described_class.new(999).name).to eq :reporting
|
167
|
+
expect(described_class.new(-123).name).to eq nil
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'supports initialization by symbol value' do
|
171
|
+
expect(described_class.new(:interactive)).to eq(5)
|
172
|
+
expect(described_class.new(:user_visible)).to eq(15)
|
173
|
+
expect(described_class.new(:eventual)).to eq(25)
|
174
|
+
expect(described_class.new(:reporting)).to eq(35)
|
175
|
+
end
|
176
|
+
|
177
|
+
it "supports predicate ('?') methods" do
|
178
|
+
expect(described_class.new(0).interactive?).to eq true
|
179
|
+
expect(described_class.new(3)).to be_interactive
|
180
|
+
expect(described_class.new(3).user_visible?).to eq false
|
181
|
+
expect(described_class.new(10)).to be_user_visible
|
182
|
+
expect(described_class.new(29)).to be_eventual
|
183
|
+
expect(described_class.new(999)).to be_reporting
|
184
|
+
expect(described_class.new(-123).interactive?).to eq false
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
113
188
|
it 'supports alert threshold methods' do
|
114
189
|
described_class.alerts = {
|
115
190
|
interactive: { age: 77.seconds },
|
@@ -151,4 +226,13 @@ RSpec.describe Delayed::Priority do
|
|
151
226
|
].sort,
|
152
227
|
).to eq [-13, 3, 5, 40]
|
153
228
|
end
|
229
|
+
|
230
|
+
it 'supports addition and subtraction' do
|
231
|
+
expect(described_class.new(0) + 10).to eq(10)
|
232
|
+
expect(10 + described_class.new(5)).to eq(15)
|
233
|
+
expect(described_class.new(0) + described_class.new(33)).to eq(33)
|
234
|
+
expect(described_class.new(10) - 5).to eq(5)
|
235
|
+
expect(15 - described_class.new(10)).to eq(5)
|
236
|
+
expect(described_class.new(5) - described_class.new(15)).to eq(-10)
|
237
|
+
end
|
154
238
|
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.5.
|
4
|
+
version: 0.5.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Griffith
|
@@ -16,10 +16,10 @@ authors:
|
|
16
16
|
- Matt Griffin
|
17
17
|
- Steve Richert
|
18
18
|
- Tobias Lütke
|
19
|
-
autorequire:
|
19
|
+
autorequire:
|
20
20
|
bindir: bin
|
21
21
|
cert_chain: []
|
22
|
-
date: 2024-01
|
22
|
+
date: 2024-05-01 00:00:00.000000000 Z
|
23
23
|
dependencies:
|
24
24
|
- !ruby/object:Gem::Dependency
|
25
25
|
name: activerecord
|
@@ -124,7 +124,7 @@ metadata:
|
|
124
124
|
bug_tracker_uri: https://github.com/betterment/delayed/issues
|
125
125
|
source_code_uri: https://github.com/betterment/delayed
|
126
126
|
rubygems_mfa_required: 'true'
|
127
|
-
post_install_message:
|
127
|
+
post_install_message:
|
128
128
|
rdoc_options: []
|
129
129
|
require_paths:
|
130
130
|
- lib
|
@@ -139,30 +139,30 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
139
|
- !ruby/object:Gem::Version
|
140
140
|
version: '0'
|
141
141
|
requirements: []
|
142
|
-
rubygems_version: 3.3.
|
143
|
-
signing_key:
|
142
|
+
rubygems_version: 3.3.26
|
143
|
+
signing_key:
|
144
144
|
specification_version: 4
|
145
145
|
summary: a multi-threaded, SQL-driven ActiveJob backend used at Betterment to process
|
146
146
|
millions of background jobs per day
|
147
147
|
test_files:
|
148
|
-
- spec/sample_jobs.rb
|
149
|
-
- spec/lifecycle_spec.rb
|
150
|
-
- spec/performable_method_spec.rb
|
151
|
-
- spec/helper.rb
|
152
|
-
- spec/psych_ext_spec.rb
|
153
|
-
- spec/worker_spec.rb
|
154
|
-
- spec/autoloaded/struct.rb
|
155
148
|
- spec/autoloaded/clazz.rb
|
156
149
|
- spec/autoloaded/instance_clazz.rb
|
157
150
|
- spec/autoloaded/instance_struct.rb
|
151
|
+
- spec/autoloaded/struct.rb
|
158
152
|
- spec/database.yml
|
159
|
-
- spec/delayed/
|
160
|
-
- spec/delayed/
|
153
|
+
- spec/delayed/active_job_adapter_spec.rb
|
154
|
+
- spec/delayed/job_spec.rb
|
161
155
|
- spec/delayed/monitor_spec.rb
|
156
|
+
- spec/delayed/plugins/instrumentation_spec.rb
|
157
|
+
- spec/delayed/priority_spec.rb
|
162
158
|
- spec/delayed/serialization/active_record_spec.rb
|
163
159
|
- spec/delayed/tasks_spec.rb
|
164
|
-
- spec/
|
165
|
-
- spec/
|
160
|
+
- spec/helper.rb
|
161
|
+
- spec/lifecycle_spec.rb
|
166
162
|
- spec/message_sending_spec.rb
|
167
163
|
- spec/performable_mailer_spec.rb
|
164
|
+
- spec/performable_method_spec.rb
|
165
|
+
- spec/psych_ext_spec.rb
|
166
|
+
- spec/sample_jobs.rb
|
167
|
+
- spec/worker_spec.rb
|
168
168
|
- spec/yaml_ext_spec.rb
|