delayed 2.2.0 → 3.0.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.
@@ -20,12 +20,12 @@ describe Delayed::Job do
20
20
  end
21
21
 
22
22
  it 'sets run_at automatically if not set' do
23
- expect(described_class.create(payload_object: ErrorJob.new).run_at).not_to be_nil
23
+ expect(described_class.enqueue(payload_object: ErrorJob.new).run_at).not_to be_nil
24
24
  end
25
25
 
26
26
  it 'does not set run_at automatically if already set' do
27
27
  later = described_class.db_time_now + 5.minutes
28
- job = described_class.create(payload_object: ErrorJob.new, run_at: later)
28
+ job = described_class.enqueue(payload_object: ErrorJob.new, run_at: later)
29
29
  expect(job.run_at).to be_within(1).of(later)
30
30
  end
31
31
 
@@ -37,12 +37,6 @@ describe Delayed::Job do
37
37
  end
38
38
 
39
39
  describe 'enqueue' do
40
- it "allows enqueue hook to modify job at DB level" do
41
- later = described_class.db_time_now + 20.minutes
42
- job = described_class.enqueue payload_object: EnqueueJobMod.new
43
- expect(described_class.find(job.id).run_at).to be_within(1).of(later)
44
- end
45
-
46
40
  context 'with a hash' do
47
41
  it "raises ArgumentError when handler doesn't respond_to :perform" do
48
42
  expect { described_class.enqueue(payload_object: Object.new) }.to raise_error(ArgumentError)
@@ -170,6 +164,151 @@ describe Delayed::Job do
170
164
  expect(job).to be_persisted
171
165
  end
172
166
  end
167
+
168
+ context 'when payload defines an :enqueue hook' do
169
+ before do
170
+ stub_const('JobWithEnqueueHook', Class.new do
171
+ def enqueue(_job); end
172
+
173
+ def perform; end
174
+ end)
175
+ end
176
+
177
+ it 'raises an error naming the payload class' do
178
+ expect { described_class.enqueue(JobWithEnqueueHook.new) }
179
+ .to raise_error(RuntimeError, ':enqueue hook on JobWithEnqueueHook is no longer supported')
180
+ end
181
+
182
+ it 'does not invoke the payload enqueue method' do
183
+ payload = JobWithEnqueueHook.new
184
+ expect(payload).not_to receive(:enqueue)
185
+ expect { described_class.enqueue(payload) }.to raise_error(RuntimeError, /:enqueue hook/)
186
+ end
187
+ end
188
+
189
+ context 'when payload does not define :enqueue' do
190
+ it 'does not raise' do
191
+ expect { described_class.enqueue(SimpleJob.new) }.not_to raise_error
192
+ end
193
+ end
194
+
195
+ context 'when payload is an ActiveJob wrapper that responds to :enqueue' do
196
+ it 'does not raise' do
197
+ wrapper = ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper.new(ActiveJobJob.new.serialize)
198
+ expect { described_class.enqueue(payload_object: wrapper) }.not_to raise_error
199
+ end
200
+ end
201
+
202
+ context 'when payload is a bare ActiveJob::Base instance' do
203
+ it 'raises' do
204
+ expect { described_class.enqueue(payload_object: ActiveJobJob.new) }.to raise_error(RuntimeError, /Delayed::Job enqueue methods do not accept ActiveJobs/)
205
+ end
206
+ end
207
+
208
+ context 'when passed a bare ActiveJob::Base instance' do
209
+ it 'raises' do
210
+ expect { described_class.enqueue(ActiveJobJob.new) }.to raise_error(RuntimeError, /Delayed::Job enqueue methods do not accept ActiveJobs/)
211
+ end
212
+ end
213
+ end
214
+
215
+ describe '.enqueue_all' do
216
+ def build_job(payload = SimpleJob.new, opts = {})
217
+ described_class.new(Delayed::Backend::JobPreparer.new(payload, opts).prepare)
218
+ end
219
+
220
+ it 'returns 0 when given no jobs' do
221
+ expect(described_class.enqueue_all([])).to eq(0)
222
+ end
223
+
224
+ it 'inserts all jobs in a single INSERT' do
225
+ jobs = Array.new(3) { build_job }
226
+ expect { described_class.enqueue_all(jobs) }
227
+ .to emit_notification('sql.active_record').with_payload(hash_including(sql: a_string_matching(/\AINSERT INTO/i)))
228
+ expect(described_class.count).to eq(3)
229
+ end
230
+
231
+ it 'returns the count of enqueued jobs' do
232
+ jobs = Array.new(3) { build_job }
233
+ expect(described_class.enqueue_all(jobs)).to eq(3)
234
+ end
235
+
236
+ it 'sets id on each job from INSERT RETURNING when supported' do
237
+ skip 'requires INSERT ... RETURNING support' unless described_class.connection.supports_insert_returning?
238
+
239
+ jobs = Array.new(2) { build_job }
240
+ described_class.enqueue_all(jobs)
241
+ expect(jobs.map(&:id)).to match_array(described_class.pluck(:id))
242
+ end
243
+
244
+ it 'fires :enqueue lifecycle once with the jobs array' do
245
+ observed = []
246
+ lifecycle_was = Delayed.lifecycle
247
+ Delayed.instance_variable_set(:@lifecycle, Delayed::Lifecycle.new)
248
+ Delayed.lifecycle.before(:enqueue) { |jobs| observed << jobs }
249
+
250
+ jobs = [build_job]
251
+ described_class.enqueue_all(jobs)
252
+
253
+ expect(observed.size).to eq(1)
254
+ expect(observed.first).to eq(jobs)
255
+ ensure
256
+ Delayed.instance_variable_set(:@lifecycle, lifecycle_was)
257
+ end
258
+
259
+ context 'when delay_jobs is false' do
260
+ before { Delayed::Worker.delay_jobs = false }
261
+
262
+ it 'inline-invokes each job and inserts nothing' do
263
+ payload = SimpleJob.new
264
+ expect(payload).to receive(:perform)
265
+ described_class.enqueue_all([build_job(payload)])
266
+ expect(described_class.count).to eq(0)
267
+ end
268
+ end
269
+
270
+ context 'when a job payload defines an :enqueue hook' do
271
+ before do
272
+ stub_const('JobWithEnqueueHook', Class.new do
273
+ def enqueue(_job); end
274
+
275
+ def perform; end
276
+ end)
277
+ end
278
+
279
+ it 'raises before inserting anything' do
280
+ jobs = [build_job(JobWithEnqueueHook.new)]
281
+ expect { described_class.enqueue_all(jobs) }
282
+ .to raise_error(RuntimeError, ':enqueue hook on JobWithEnqueueHook is no longer supported')
283
+ expect(described_class.count).to eq(0)
284
+ end
285
+ end
286
+
287
+ context 'when a job payload is a bare ActiveJob::Base instance' do
288
+ it 'raises' do
289
+ jobs = [build_job(ActiveJobJob.new)]
290
+ expect { described_class.enqueue_all(jobs) }.to raise_error(RuntimeError, /Delayed::Job enqueue methods do not accept ActiveJobs/)
291
+ end
292
+ end
293
+ end
294
+
295
+ describe '#hook' do
296
+ context 'with :enqueue' do
297
+ before do
298
+ stub_const('JobWithEnqueueHook', Class.new do
299
+ def enqueue(_job); end
300
+
301
+ def perform; end
302
+ end)
303
+ end
304
+
305
+ it 'raises rather than invoking the payload hook' do
306
+ job = described_class.new(payload_object: JobWithEnqueueHook.new)
307
+ expect(job.payload_object).not_to receive(:enqueue)
308
+ expect { job.hook(:enqueue) }
309
+ .to raise_error(RuntimeError, ':enqueue hook is no longer supported')
310
+ end
311
+ end
173
312
  end
174
313
 
175
314
  describe 'callbacks' do
@@ -187,9 +326,9 @@ describe Delayed::Job do
187
326
 
188
327
  it 'calls before and after callbacks' do
189
328
  job = described_class.enqueue(CallbackJob.new)
190
- expect(CallbackJob.messages).to eq(['enqueue'])
329
+ expect(CallbackJob.messages).to eq([])
191
330
  job.invoke_job
192
- expect(CallbackJob.messages).to eq(%w(enqueue before perform success after))
331
+ expect(CallbackJob.messages).to eq(%w(before perform success after))
193
332
  end
194
333
 
195
334
  it 'calls the after callback with an error' do
@@ -197,14 +336,14 @@ describe Delayed::Job do
197
336
  expect(job.payload_object).to receive(:perform).and_raise(RuntimeError.new('fail'))
198
337
 
199
338
  expect { job.invoke_job }.to raise_error(RuntimeError, 'fail')
200
- expect(CallbackJob.messages).to eq(['enqueue', 'before', 'error: RuntimeError', 'after'])
339
+ expect(CallbackJob.messages).to eq(['before', 'error: RuntimeError', 'after'])
201
340
  end
202
341
 
203
342
  it 'calls error when before raises an error' do
204
343
  job = described_class.enqueue(CallbackJob.new)
205
344
  expect(job.payload_object).to receive(:before).and_raise(RuntimeError.new('fail'))
206
345
  expect { job.invoke_job }.to raise_error(RuntimeError, 'fail')
207
- expect(CallbackJob.messages).to eq(['enqueue', 'error: RuntimeError', 'after'])
346
+ expect(CallbackJob.messages).to eq(['error: RuntimeError', 'after'])
208
347
  end
209
348
  end
210
349
 
@@ -462,26 +601,23 @@ describe Delayed::Job do
462
601
  describe '#name' do
463
602
  context 'when name column is populated' do
464
603
  it 'is the class name of the job that was enqueued' do
465
- job = described_class.new(payload_object: ErrorJob.new)
604
+ job = described_class.enqueue(payload_object: ErrorJob.new)
466
605
  expect(job.name).to eq('ErrorJob')
467
- job.save!
468
606
  expect(job.reload.name).to eq('ErrorJob')
469
607
  expect(described_class.group(:name).count).to eq('ErrorJob' => 1)
470
608
  end
471
609
 
472
610
  it 'is the class name of the performable job if it is an ActiveJob' do
473
611
  job_wrapper = ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper.new(ActiveJobJob.new.serialize)
474
- job = described_class.new(payload_object: job_wrapper)
612
+ job = described_class.enqueue(payload_object: job_wrapper)
475
613
  expect(job.name).to eq('ActiveJobJob')
476
- job.save!
477
614
  expect(job.reload.name).to eq('ActiveJobJob')
478
615
  expect(described_class.group(:name).count).to eq('ActiveJobJob' => 1)
479
616
  end
480
617
 
481
618
  it 'is the returned display_name if display_name is defined on the job object' do
482
- job = described_class.new(payload_object: NamedJob.new)
619
+ job = described_class.enqueue(payload_object: NamedJob.new)
483
620
  expect(job.name).to eq('named_job')
484
- job.save!
485
621
  expect(job.reload.name).to eq('named_job')
486
622
  expect(described_class.group(:name).count).to eq('named_job' => 1)
487
623
  end
@@ -493,25 +629,38 @@ describe Delayed::Job do
493
629
  end
494
630
 
495
631
  it 'is the custom name value when set explicitly' do
496
- job = described_class.new(payload_object: ErrorJob.new)
497
- job.name = 'Custom Name'
498
- job.save!
632
+ job = described_class.enqueue(payload_object: ErrorJob.new, name: 'Custom Name')
499
633
  expect(job.reload.name).to eq('Custom Name')
500
634
  expect(described_class.group(:name).count).to eq('Custom Name' => 1)
501
635
  end
502
636
  end
503
637
 
504
638
  context 'when name column is NULL' do
639
+ before do
640
+ ActiveRecord::Schema.define do
641
+ ValidateRunAtAndNameNotNull.migrate(:down)
642
+ AddRunAtAndNameNotNullCheck.migrate(:down)
643
+ end
644
+ described_class.reset_column_information
645
+ end
646
+
647
+ after do
648
+ described_class.delete_all
649
+ ActiveRecord::Schema.define do
650
+ AddRunAtAndNameNotNullCheck.migrate(:up)
651
+ ValidateRunAtAndNameNotNull.migrate(:up)
652
+ end
653
+ described_class.reset_column_information
654
+ end
655
+
505
656
  it 'is the class name of the job that was enqueued' do
506
- job = described_class.create(payload_object: ErrorJob.new)
507
- job.update_column(:name, nil) # rubocop:disable Rails/SkipsModelValidations
657
+ job = described_class.enqueue(payload_object: ErrorJob.new)
508
658
  expect(job.reload.name).to eq('ErrorJob')
509
659
  end
510
660
 
511
661
  it 'is the class name of the performable job if it is an ActiveJob' do
512
662
  job_wrapper = ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper.new(ActiveJobJob.new.serialize)
513
- job = described_class.create(payload_object: job_wrapper)
514
- job.update_column(:name, nil) # rubocop:disable Rails/SkipsModelValidations
663
+ job = described_class.enqueue(payload_object: job_wrapper)
515
664
  expect(job.reload.name).to eq('ActiveJobJob')
516
665
  end
517
666
 
@@ -542,7 +691,7 @@ describe Delayed::Job do
542
691
  end
543
692
 
544
693
  it 'is the class name of the job that was enqueued' do
545
- job = described_class.new(payload_object: ErrorJob.new)
694
+ job = described_class.new(payload_object: ErrorJob.new, run_at: Time.current)
546
695
  expect(job.name).to eq('ErrorJob')
547
696
  job.save!
548
697
  expect(job.reload.name).to eq('ErrorJob')
@@ -550,14 +699,14 @@ describe Delayed::Job do
550
699
 
551
700
  it 'is the class name of the performable job if it is an ActiveJob' do
552
701
  job_wrapper = ActiveJob::QueueAdapters::DelayedJobAdapter::JobWrapper.new(ActiveJobJob.new.serialize)
553
- job = described_class.new(payload_object: job_wrapper)
702
+ job = described_class.new(payload_object: job_wrapper, run_at: Time.current)
554
703
  expect(job.name).to eq('ActiveJobJob')
555
704
  job.save!
556
705
  expect(job.reload.name).to eq('ActiveJobJob')
557
706
  end
558
707
 
559
708
  it 'is the returned display_name if display_name is defined on the job object' do
560
- job = described_class.new(payload_object: NamedJob.new)
709
+ job = described_class.new(payload_object: NamedJob.new, run_at: Time.current)
561
710
  expect(job.name).to eq('named_job')
562
711
  job.save!
563
712
  expect(job.reload.name).to eq('named_job')
@@ -835,7 +984,7 @@ describe Delayed::Job do
835
984
  describe 'running a job' do
836
985
  it 'fails after Worker.max_run_time' do
837
986
  Delayed::Worker.max_run_time = 1.second
838
- job = described_class.create payload_object: LongRunningJob.new
987
+ job = described_class.enqueue payload_object: LongRunningJob.new
839
988
  worker.perform(job)
840
989
  expect(job.error).not_to be_nil
841
990
  expect(job.reload.last_error).to match(/expired/)
@@ -845,7 +994,7 @@ describe Delayed::Job do
845
994
 
846
995
  context 'when the job raises a deserialization error' do
847
996
  it 'marks the job as failed' do
848
- job = described_class.create! payload_object: LongRunningJob.new
997
+ job = described_class.enqueue payload_object: LongRunningJob.new
849
998
  job.update_columns(handler: '--- !ruby/object:JobThatDoesNotExist {}') # rubocop:disable Rails/SkipsModelValidations
850
999
  expect_any_instance_of(described_class).to receive(:destroy_failed_jobs?).and_return(false)
851
1000
  worker.work_off
@@ -900,13 +1049,13 @@ describe Delayed::Job do
900
1049
 
901
1050
  context 'reschedule' do
902
1051
  before do
903
- @job = described_class.create payload_object: SimpleJob.new
1052
+ @job = described_class.enqueue payload_object: SimpleJob.new
904
1053
  end
905
1054
 
906
1055
  shared_examples_for 'any failure more than Worker.max_attempts times' do
907
1056
  context "when the job's payload has a #failure hook" do
908
1057
  before do
909
- @job = described_class.create payload_object: OnPermanentFailureJob.new
1058
+ @job = described_class.enqueue payload_object: OnPermanentFailureJob.new
910
1059
  expect(@job.payload_object).to respond_to(:failure)
911
1060
  end
912
1061
 
@@ -123,6 +123,7 @@ RSpec.describe Delayed::Monitor do
123
123
  run_at: now,
124
124
  queue: 'default',
125
125
  handler: "--- !ruby/object:SimpleJob\n",
126
+ name: 'SimpleJob',
126
127
  attempts: 0,
127
128
  }
128
129
  end
@@ -3,6 +3,47 @@ require 'helper'
3
3
  RSpec.describe Delayed::Plugins::Instrumentation do
4
4
  let!(:job) { Delayed::Job.enqueue SimpleJob.new, priority: 13, queue: 'test' }
5
5
 
6
+ it 'emits delayed.job.enqueue when a job is enqueued' do
7
+ expect { Delayed::Job.enqueue SimpleJob.new }.to emit_notification('delayed.job.enqueue').with_payload(
8
+ jobs: [
9
+ hash_including(
10
+ job_name: 'SimpleJob',
11
+ table: 'delayed_jobs',
12
+ database: current_database,
13
+ database_adapter: current_adapter,
14
+ job: an_instance_of(Delayed::Job),
15
+ ),
16
+ ],
17
+ )
18
+ end
19
+
20
+ it 'emits a single delayed.job.enqueue when a batch is enqueued via the ActiveJob adapter' do
21
+ job_class = Class.new(ActiveJob::Base) do
22
+ def perform; end
23
+ end
24
+ stub_const('BatchedJob', job_class)
25
+
26
+ adapter_was = ActiveJob::Base.queue_adapter
27
+ ActiveJob::Base.queue_adapter = :delayed
28
+ begin
29
+ jobs = Array.new(3) { BatchedJob.new }
30
+ expect { ActiveJob::Base.queue_adapter.enqueue_all(jobs) }
31
+ .to emit_notification('delayed.job.enqueue').with_payload(
32
+ jobs: Array.new(3) {
33
+ hash_including(
34
+ job_name: 'BatchedJob',
35
+ table: 'delayed_jobs',
36
+ database: current_database,
37
+ database_adapter: current_adapter,
38
+ job: an_instance_of(Delayed::Job),
39
+ )
40
+ },
41
+ )
42
+ ensure
43
+ ActiveJob::Base.queue_adapter = adapter_was
44
+ end
45
+ end
46
+
6
47
  it 'emits delayed.job.run' do
7
48
  expect { Delayed::Worker.new.work_off }.to emit_notification('delayed.job.run').with_payload(
8
49
  job_name: 'SimpleJob',
data/spec/helper.rb CHANGED
@@ -92,6 +92,8 @@ ActiveRecord::Schema.define do
92
92
  run_migration(IndexFailedJobs)
93
93
  run_migration(SetPostgresFillfactor)
94
94
  run_migration(RemoveLegacyIndex)
95
+ run_migration(AddRunAtAndNameNotNullCheck)
96
+ run_migration(ValidateRunAtAndNameNotNull)
95
97
 
96
98
  # Test that these index migrations can be re-applied idempotently.
97
99
  # (In case identical indexes had been manually applied previously.)
@@ -266,6 +268,10 @@ def current_database
266
268
  end
267
269
  end
268
270
 
271
+ def current_database_name
272
+ current_adapter == 'sqlite3' ? 'tmp/database.sqlite' : 'delayed_job_test'
273
+ end
274
+
269
275
  QueryUnderTest = Struct.new(:sql, :connection) do
270
276
  def self.for(query, connection: ActiveRecord::Base.connection)
271
277
  new(query.respond_to?(:to_sql) ? query.to_sql : query.to_s, connection)
@@ -305,10 +311,12 @@ QueryUnderTest = Struct.new(:sql, :connection) do
305
311
  def postgresql_explain
306
312
  connection.execute("SET seq_page_cost = 100")
307
313
  connection.execute("SET enable_hashagg = off")
314
+ connection.execute("SET enable_incremental_sort = off")
308
315
  connection.execute("SET plan_cache_mode TO force_generic_plan")
309
316
  connection.execute("EXPLAIN (VERBOSE) #{sql}").values.flatten.join("\n")
310
317
  ensure
311
318
  connection.execute("RESET plan_cache_mode")
319
+ connection.execute("RESET enable_incremental_sort")
312
320
  connection.execute("RESET enable_hashagg")
313
321
  connection.execute("RESET seq_page_cost")
314
322
  end
@@ -334,6 +342,7 @@ QueryUnderTest = Struct.new(:sql, :connection) do
334
342
  run_at: now + (future ? i.minutes : -i.minutes),
335
343
  queue: "queue_#{i}",
336
344
  handler: "--- !ruby/object:SimpleJob\n",
345
+ name: 'SimpleJob',
337
346
  attempts: erroring ? i : 0,
338
347
  failed_at: failed ? now - i.minutes : nil,
339
348
  locked_at: locked ? now - i.seconds : nil,
@@ -3,7 +3,7 @@ require 'helper'
3
3
  describe Delayed::Lifecycle do
4
4
  let(:lifecycle) { described_class.new }
5
5
  let(:callback) { lambda { |*_args| } }
6
- let(:arguments) { [1] }
6
+ let(:arguments) { [%i(job_a job_b)] }
7
7
  let(:behavior) { double(Object, before!: nil, after!: nil, inside!: nil) }
8
8
  let(:wrapped_block) { proc { behavior.inside! } }
9
9
 
@@ -136,23 +136,13 @@ describe Delayed::MessageSending do
136
136
  }.to change { Delayed::Job.count }.by(1)
137
137
  end
138
138
 
139
- it 'does delay when delay_jobs is a proc returning true' do
140
- Delayed::Worker.delay_jobs = ->(_job) { true }
139
+ it 'raises when delay_jobs is a Proc' do
140
+ Delayed::Worker.delay_jobs = -> { true }
141
141
  fairy_tail = FairyTail.new
142
142
  expect {
143
143
  expect {
144
144
  fairy_tail.delay.tell('a', kwarg: 'b')
145
- }.not_to change { fairy_tail.happy_ending }
146
- }.to change { Delayed::Job.count }.by(1)
147
- end
148
-
149
- it 'does not delay the job when delay_jobs is a proc returning false' do
150
- Delayed::Worker.delay_jobs = ->(_job) { false }
151
- fairy_tail = FairyTail.new
152
- expect {
153
- expect {
154
- fairy_tail.delay.tell('a', kwarg: 'b')
155
- }.to change { fairy_tail.happy_ending }.from(nil).to %w(a b)
145
+ }.to raise_error('Delayed::Worker.delay_jobs may not be a Proc')
156
146
  }.not_to(change { Delayed::Job.count })
157
147
  end
158
148
  end
@@ -95,12 +95,6 @@ describe Delayed::PerformableMethod do
95
95
  end
96
96
  end
97
97
 
98
- it 'delegates enqueue hook to object' do
99
- story = Story.create
100
- expect(story).to receive(:enqueue).with(an_instance_of(Delayed::Job))
101
- story.delay.tell
102
- end
103
-
104
98
  it 'delegates error hook to object' do
105
99
  story = Story.create
106
100
  expect(story).to receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))
data/spec/sample_jobs.rb CHANGED
@@ -77,10 +77,6 @@ end
77
77
  class CallbackJob
78
78
  cattr_accessor :messages
79
79
 
80
- def enqueue(_job)
81
- self.class.messages << 'enqueue'
82
- end
83
-
84
80
  def before(_job)
85
81
  self.class.messages << 'before'
86
82
  end
@@ -106,12 +102,6 @@ class CallbackJob
106
102
  end
107
103
  end
108
104
 
109
- class EnqueueJobMod < SimpleJob
110
- def enqueue(job)
111
- job.run_at = 20.minutes.from_now
112
- end
113
- end
114
-
115
105
  class ActiveJobJob < ActiveJob::Base # rubocop:disable Rails/ApplicationJob
116
106
  def perform(*args, **kwargs); end
117
107
  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: 2.2.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Griffith
@@ -19,7 +19,7 @@ authors:
19
19
  autorequire:
20
20
  bindir: bin
21
21
  cert_chain: []
22
- date: 2026-02-12 00:00:00.000000000 Z
22
+ date: 2026-06-08 00:00:00.000000000 Z
23
23
  dependencies:
24
24
  - !ruby/object:Gem::Dependency
25
25
  name: activerecord
@@ -66,13 +66,15 @@ files:
66
66
  - README.md
67
67
  - Rakefile
68
68
  - app/models/delayed/job.rb
69
- - db/migrate/1_create_delayed_jobs.rb
70
- - db/migrate/2_add_name_to_delayed_jobs.rb
71
- - db/migrate/3_add_index_to_delayed_jobs_name.rb
72
- - db/migrate/4_index_live_jobs.rb
73
- - db/migrate/5_index_failed_jobs.rb
74
- - db/migrate/6_set_postgres_fillfactor.rb
75
- - db/migrate/7_remove_legacy_index.rb
69
+ - db/migrate/01_create_delayed_jobs.rb
70
+ - db/migrate/02_add_name_to_delayed_jobs.rb
71
+ - db/migrate/03_add_index_to_delayed_jobs_name.rb
72
+ - db/migrate/04_index_live_jobs.rb
73
+ - db/migrate/05_index_failed_jobs.rb
74
+ - db/migrate/06_set_postgres_fillfactor.rb
75
+ - db/migrate/07_remove_legacy_index.rb
76
+ - db/migrate/08_add_run_at_and_name_not_null_check.rb
77
+ - db/migrate/09_validate_run_at_and_name_not_null.rb
76
78
  - lib/delayed.rb
77
79
  - lib/delayed/active_job_adapter.rb
78
80
  - lib/delayed/backend/base.rb
@@ -128,7 +130,7 @@ homepage: http://github.com/betterment/delayed
128
130
  licenses:
129
131
  - MIT
130
132
  metadata:
131
- changelog_uri: https://github.com/betterment/delayed/blob/main/CHANGELOG.md
133
+ changelog_uri: https://github.com/betterment/delayed/releases
132
134
  bug_tracker_uri: https://github.com/betterment/delayed/issues
133
135
  source_code_uri: https://github.com/betterment/delayed
134
136
  rubygems_mfa_required: 'true'