delayed 0.5.3 → 0.5.5
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/lib/delayed/worker.rb +24 -26
- data/spec/delayed/active_job_adapter_spec.rb +24 -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: ae36c9e652d4fb6ce28f8897b0e7b03b7777ce9907a74973924111b735bca3ae
|
|
4
|
+
data.tar.gz: 0d4c27d0bf1f7e256fa85914086a0711c6406b4be5e88f211eccbd921c001718
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cbae79e450983c1dd968b5f9959b4497758c32cc2c21a45ecea5b41dc1d7829fac2699d0a8cea635369d276eaec5b07ce8d7fa292674578ff62690823bc163fc
|
|
7
|
+
data.tar.gz: df37746eee87f40792499e02421f82a2fc4afa4317e168bdb440f3bed1ba737c761469092098f99e2aa3fb163f50981e6b19a83a4859e91871ac8f046363f630
|
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 == :always
|
|
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)
|
data/lib/delayed/worker.rb
CHANGED
|
@@ -89,22 +89,17 @@ module Delayed
|
|
|
89
89
|
# Exit early if interrupted.
|
|
90
90
|
def work_off(num = 100)
|
|
91
91
|
success = Concurrent::AtomicFixnum.new(0)
|
|
92
|
-
|
|
92
|
+
total = 0
|
|
93
93
|
|
|
94
|
-
num
|
|
94
|
+
while total < num
|
|
95
95
|
jobs = reserve_jobs
|
|
96
96
|
break if jobs.empty?
|
|
97
97
|
|
|
98
|
+
total += jobs.length
|
|
98
99
|
pool = Concurrent::FixedThreadPool.new(jobs.length)
|
|
99
100
|
jobs.each do |job|
|
|
100
101
|
pool.post do
|
|
101
|
-
|
|
102
|
-
if run_job(job)
|
|
103
|
-
success.increment
|
|
104
|
-
else
|
|
105
|
-
failure.increment
|
|
106
|
-
end
|
|
107
|
-
end
|
|
102
|
+
success.increment if run_job(job)
|
|
108
103
|
end
|
|
109
104
|
end
|
|
110
105
|
|
|
@@ -114,7 +109,7 @@ module Delayed
|
|
|
114
109
|
break if stop? # leave if we're exiting
|
|
115
110
|
end
|
|
116
111
|
|
|
117
|
-
[success,
|
|
112
|
+
[success.value, total - success.value]
|
|
118
113
|
end
|
|
119
114
|
|
|
120
115
|
def run_thread_callbacks(job, &block)
|
|
@@ -122,30 +117,33 @@ module Delayed
|
|
|
122
117
|
end
|
|
123
118
|
|
|
124
119
|
def run(job)
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
job.
|
|
120
|
+
run_thread_callbacks(job) do
|
|
121
|
+
metadata = {
|
|
122
|
+
status: 'RUNNING',
|
|
123
|
+
name: job.name,
|
|
124
|
+
run_at: job.run_at,
|
|
125
|
+
created_at: job.created_at,
|
|
126
|
+
priority: job.priority,
|
|
127
|
+
queue: job.queue,
|
|
128
|
+
attempts: job.attempts,
|
|
129
|
+
enqueued_for: (Time.current - job.created_at).round,
|
|
130
|
+
}
|
|
131
|
+
job_say job, metadata.to_json
|
|
132
|
+
run_time = Benchmark.realtime do
|
|
133
|
+
Timeout.timeout(max_run_time(job).to_i, WorkerTimeout) do
|
|
134
|
+
job.invoke_job
|
|
135
|
+
end
|
|
136
|
+
job.destroy
|
|
139
137
|
end
|
|
140
|
-
job
|
|
138
|
+
job_say job, format('COMPLETED after %.4f seconds', run_time)
|
|
141
139
|
end
|
|
142
|
-
job_say job, format('COMPLETED after %.4f seconds', run_time)
|
|
143
140
|
true # did work
|
|
144
141
|
rescue DeserializationError => e
|
|
145
142
|
job_say job, "FAILED permanently with #{e.class.name}: #{e.message}", 'error'
|
|
146
143
|
|
|
147
144
|
job.error = e
|
|
148
145
|
failed(job)
|
|
146
|
+
false # work failed
|
|
149
147
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
|
150
148
|
self.class.lifecycle.run_callbacks(:error, self, job) { handle_failed_job(job, e) }
|
|
151
149
|
false # work failed
|
|
@@ -287,6 +287,30 @@ 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 :always' do
|
|
292
|
+
before do
|
|
293
|
+
JobClass.include ActiveJob::EnqueueAfterTransactionCommit # normally run in an ActiveJob railtie
|
|
294
|
+
JobClass.enqueue_after_transaction_commit = :always
|
|
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
|
+
|
|
302
|
+
context 'when the given job sets enqueue_after_transaction_commit to :never' do
|
|
303
|
+
before do
|
|
304
|
+
JobClass.include ActiveJob::EnqueueAfterTransactionCommit # normally run in an ActiveJob railtie
|
|
305
|
+
JobClass.enqueue_after_transaction_commit = :never
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
it 'does not raises an exception on enqueue' do
|
|
309
|
+
expect { JobClass.perform_later }.not_to raise_error(Delayed::ActiveJobAdapter::UnsafeEnqueueError)
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
|
|
290
314
|
context 'when using the ActiveJob test adapter' do
|
|
291
315
|
let(:queue_adapter) { :test }
|
|
292
316
|
|
|
@@ -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.5
|
|
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-
|
|
22
|
+
date: 2024-08-13 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
|