inst-jobs 3.0.9 → 3.0.13

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 953dc843cf3274fd2fc62ea200636e9663147e6aec0465ca4d258216a3394fc2
4
- data.tar.gz: 46012d5b8466f7178c868564ebb2500f159ff769f879d263247ac4abfa196335
3
+ metadata.gz: c1369efb0e72de3f01f922b7f77a95a6c5dd1979aaec11cfd76cdc4507202428
4
+ data.tar.gz: 244a543711c3ceab301f4ea0f30bb238e47330921059ec27133a7a2de44389f7
5
5
  SHA512:
6
- metadata.gz: 124abbec91c97e76383eeb503ccc125333cad963120d8e58df674f910860beebbd8f6069b6a83eeb2fdc03b8a475ffe11472be93e584d85195eba0d1226dccae
7
- data.tar.gz: b422a5a470cea805d37b9398b7a380191b50cc387d5f6ce75245b0f677e4e6b73d816f4cf8ae1a2433b4c8533496394d5f275a7aa52d08e3b9e949ef77473871
6
+ metadata.gz: '09ce7c560febe39082502641d62e9309f515d026eb95d840e3645fbb2725d9eb6c70f2b147402a44d462bc5761c8f4727739e87a7f4a6acbed391868ae024d2e'
7
+ data.tar.gz: d0332dc2e652adf67b93f61122d535a7e48f20d48e9d66a08d2e5fc75d08c4be1c7e15b4656c7f1bfc4102a389bd23d256b4d43cb88b914e98ce9a0ea67ddd3c
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class AddFailedJobsIndicies < ActiveRecord::Migration[5.2]
4
+ disable_ddl_transaction!
5
+
6
+ def change
7
+ add_index :failed_jobs, :failed_at, algorithm: :concurrently
8
+ add_index :failed_jobs, :strand, where: "strand IS NOT NULL", algorithm: :concurrently
9
+ add_index :failed_jobs, :singleton, where: "singleton IS NOT NULL", algorithm: :concurrently
10
+ add_index :failed_jobs, :tag, algorithm: :concurrently
11
+ end
12
+ end
@@ -62,11 +62,21 @@ module Delayed
62
62
  _write_attribute(column, current_time) unless attribute_present?(column)
63
63
  end
64
64
 
65
- attribute_names = attribute_names_for_partial_writes
65
+ attribute_names = if Rails.version < "7.0"
66
+ attribute_names_for_partial_writes
67
+ else
68
+ attribute_names_for_partial_inserts
69
+ end
66
70
  attribute_names = attributes_for_create(attribute_names)
67
71
  values = attributes_with_values(attribute_names)
68
72
 
69
- im = self.class.arel_table.compile_insert(self.class.send(:_substitute_values, values))
73
+ im = if Rails.version < "7.0"
74
+ self.class.arel_table.compile_insert(self.class.send(:_substitute_values, values))
75
+ else
76
+ im = Arel::InsertManager.new(self.class.arel_table)
77
+ im.insert(values.transform_keys { |name| self.class.arel_table[name] })
78
+ im
79
+ end
70
80
 
71
81
  lock_and_insert = values["strand"] && instance_of?(Job)
72
82
  # can't use prepared statements if we're combining multiple statemenets
@@ -101,7 +111,8 @@ module Delayed
101
111
  # but we don't need to lock when inserting into Delayed::Failed
102
112
  if values["strand"] && instance_of?(Job)
103
113
  fn_name = connection.quote_table_name("half_md5_as_bigint")
104
- sql = "SELECT pg_advisory_xact_lock(#{fn_name}(#{connection.quote(values['strand'])})); #{sql}"
114
+ quoted_strand = connection.quote(Rails.version < "7.0" ? values["strand"] : values["strand"].value)
115
+ sql = "SELECT pg_advisory_xact_lock(#{fn_name}(#{quoted_strand})); #{sql}"
105
116
  end
106
117
  result = connection.execute(sql, "#{self.class} Create")
107
118
  self.id = result.values.first&.first
@@ -471,7 +482,7 @@ module Delayed
471
482
  transaction do
472
483
  # for db performance reasons, we only need one process doing this at a time
473
484
  # so if we can't get an advisory lock, just abort. we'll try again soon
474
- return unless attempt_advisory_lock(prefetch_jobs_lock_name)
485
+ next unless attempt_advisory_lock(prefetch_jobs_lock_name)
475
486
 
476
487
  horizon = db_time_now - (Settings.parent_process[:prefetched_jobs_timeout] * 4)
477
488
  where("locked_by LIKE 'prefetch:%' AND locked_at<?", horizon).update_all(locked_at: nil, locked_by: nil)
@@ -568,6 +579,10 @@ module Delayed
568
579
  class Failed < Job
569
580
  include Delayed::Backend::Base
570
581
  self.table_name = :failed_jobs
582
+
583
+ def self.cleanup_old_jobs(before_date, batch_size: 10_000)
584
+ where("failed_at < ?", before_date).in_batches(of: batch_size).delete_all
585
+ end
571
586
  end
572
587
  end
573
588
  end
@@ -36,7 +36,7 @@ module Delayed
36
36
  Delayed::Job.transaction do
37
37
  # for db performance reasons, we only need one process doing this at a time
38
38
  # so if we can't get an advisory lock, just abort. we'll try again soon
39
- return unless Delayed::Job.attempt_advisory_lock("Delayed::Periodic#audit_queue")
39
+ next unless Delayed::Job.attempt_advisory_lock("Delayed::Periodic#audit_queue")
40
40
 
41
41
  perform_audit!
42
42
  end
@@ -33,6 +33,7 @@ module Delayed
33
33
 
34
34
  SETTINGS_WITH_ARGS = %i[
35
35
  job_detailed_log_format
36
+ job_short_log_format
36
37
  num_strands
37
38
  ].freeze
38
39
 
@@ -137,6 +138,7 @@ module Delayed
137
138
  self.job_detailed_log_format = lambda { |job|
138
139
  job.to_json(include_root: false, only: %w[tag strand singleton priority attempts created_at max_attempts source])
139
140
  }
141
+ self.job_short_log_format = ->(_job) { "" }
140
142
 
141
143
  # Send workers KILL after QUIT if they haven't exited within the
142
144
  # slow_exit_timeout
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Delayed
4
- VERSION = "3.0.9"
4
+ VERSION = "3.0.13"
5
5
  end
@@ -34,7 +34,7 @@ module Delayed
34
34
  # no other worker is trying to do this right now (and if we abandon the
35
35
  # operation, the transaction will end, releasing the advisory lock).
36
36
  result = Delayed::Job.attempt_advisory_lock("Delayed::Worker::HealthCheck#reschedule_abandoned_jobs")
37
- return unless result
37
+ next unless result
38
38
 
39
39
  horizon = 5.minutes.ago
40
40
 
@@ -220,7 +220,7 @@ module Delayed
220
220
  end
221
221
  job.destroy
222
222
  end
223
- logger.info("Completed #{log_job(job)} #{format('%.0fms', (runtime * 1000))}")
223
+ logger.info("Completed #{log_job(job, :short)} #{format('%.0fms', (runtime * 1000))}")
224
224
  end
225
225
  rescue ::Delayed::RetriableError => e
226
226
  can_retry = job.attempts + 1 < job.inferred_max_attempts
@@ -269,7 +269,7 @@ module Delayed
269
269
  when :long
270
270
  "#{job.full_name} #{Settings.job_detailed_log_format.call(job)}"
271
271
  else
272
- job.full_name
272
+ "#{job.full_name} #{Settings.job_short_log_format.call(job)}".strip
273
273
  end
274
274
  end
275
275
 
@@ -28,13 +28,13 @@ describe "Delayed::Backed::ActiveRecord::Job" do
28
28
 
29
29
  it "does not allow a second worker to get exclusive access if already successfully processed by worker1" do
30
30
  @job.destroy
31
- expect(@job_copy_for_worker2.send(:lock_exclusively!, "worker2")).to eq(false)
31
+ expect(@job_copy_for_worker2.send(:lock_exclusively!, "worker2")).to be(false)
32
32
  end
33
33
 
34
34
  it "doesn't allow a second worker to get exclusive access if failed to be " \
35
35
  "processed by worker1 and run_at time is now in future (due to backing off behaviour)" do
36
36
  @job.update(attempts: 1, run_at: 1.day.from_now)
37
- expect(@job_copy_for_worker2.send(:lock_exclusively!, "worker2")).to eq(false)
37
+ expect(@job_copy_for_worker2.send(:lock_exclusively!, "worker2")).to be(false)
38
38
  end
39
39
 
40
40
  it "selects the next job at random if enabled" do
@@ -55,13 +55,13 @@ describe "Delayed::Backed::ActiveRecord::Job" do
55
55
 
56
56
  it "unlocks a successfully locked job and persist the job's unlocked state" do
57
57
  job = Delayed::Job.create payload_object: SimpleJob.new
58
- expect(job.send(:lock_exclusively!, "worker1")).to eq(true)
58
+ expect(job.send(:lock_exclusively!, "worker1")).to be(true)
59
59
  job.reload
60
60
  job.unlock
61
61
  job.save!
62
62
  job.reload
63
- expect(job.locked_by).to eq(nil)
64
- expect(job.locked_at).to eq(nil)
63
+ expect(job.locked_by).to be_nil
64
+ expect(job.locked_at).to be_nil
65
65
  end
66
66
 
67
67
  describe "bulk_update failed jobs" do
@@ -85,7 +85,7 @@ describe "Delayed::Backed::ActiveRecord::Job" do
85
85
  before do
86
86
  2.times do
87
87
  j = Delayed::Job.create(payload_object: SimpleJob.new)
88
- expect(j.send(:lock_exclusively!, "worker1")).to eq(true)
88
+ expect(j.send(:lock_exclusively!, "worker1")).to be(true)
89
89
  j.fail!
90
90
  end
91
91
  end
@@ -100,6 +100,15 @@ describe "Delayed::Backed::ActiveRecord::Job" do
100
100
  failed_count = Delayed::Job::Failed.count
101
101
  expect(Delayed::Job.bulk_update("destroy", flavor: "failed", query: @query)).to eq(failed_count)
102
102
  end
103
+
104
+ it "deletes all failed jobs before a given date" do
105
+ Delayed::Job::Failed.first.update!(failed_at: 3.hours.ago)
106
+ Delayed::Job::Failed.last.update!(failed_at: 1.hour.ago)
107
+
108
+ expect(Delayed::Job::Failed.count).to eq 2
109
+ Delayed::Job::Failed.cleanup_old_jobs(2.hours.ago)
110
+ expect(Delayed::Job::Failed.count).to eq 1
111
+ end
103
112
  end
104
113
  end
105
114
 
@@ -170,13 +179,13 @@ describe "Delayed::Backed::ActiveRecord::Job" do
170
179
  it "sets one job as next_in_strand at a time with max_concurrent of 1" do
171
180
  job1 = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs"])
172
181
  job1.reload
173
- expect(job1.next_in_strand).to eq(true)
182
+ expect(job1.next_in_strand).to be(true)
174
183
  job2 = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs"])
175
184
  job2.reload
176
- expect(job2.next_in_strand).to eq(false)
185
+ expect(job2.next_in_strand).to be(false)
177
186
  run_job(job1)
178
187
  job2.reload
179
- expect(job2.next_in_strand).to eq(true)
188
+ expect(job2.next_in_strand).to be(true)
180
189
  end
181
190
 
182
191
  it "sets multiple jobs as next_in_strand at a time based on max_concurrent" do
@@ -187,16 +196,16 @@ describe "Delayed::Backed::ActiveRecord::Job" do
187
196
  }) do
188
197
  job1 = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs"])
189
198
  job1.reload
190
- expect(job1.next_in_strand).to eq(true)
199
+ expect(job1.next_in_strand).to be(true)
191
200
  job2 = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs"])
192
201
  job2.reload
193
- expect(job2.next_in_strand).to eq(true)
202
+ expect(job2.next_in_strand).to be(true)
194
203
  job3 = Delayed::Job.enqueue(SimpleJob.new, n_strand: ["njobs"])
195
204
  job3.reload
196
- expect(job3.next_in_strand).to eq(false)
205
+ expect(job3.next_in_strand).to be(false)
197
206
  run_job(job1)
198
207
  job3.reload
199
- expect(job3.next_in_strand).to eq(true)
208
+ expect(job3.next_in_strand).to be(true)
200
209
  end
201
210
  end
202
211
  end
@@ -26,6 +26,6 @@ RSpec.describe Delayed::WorkQueue::InProcess do
26
26
  end
27
27
  job = subject.get_and_lock_next_available(*args)
28
28
  expect(job).to eq(:job)
29
- expect(called).to eq(true)
29
+ expect(called).to be(true)
30
30
  end
31
31
  end
@@ -255,7 +255,7 @@ RSpec.describe Delayed::WorkQueue::ParentProcess::Server do
255
255
  subject.run_once
256
256
 
257
257
  expect(Marshal.load(client)).to eq(job)
258
- expect(called).to eq(true)
258
+ expect(called).to be(true)
259
259
  end
260
260
 
261
261
  it "deletes the correct worker when transferring jobs" do
@@ -85,13 +85,14 @@ describe Delayed::Worker do
85
85
  end
86
86
 
87
87
  it "logging format can be changed with settings" do
88
- Delayed::Settings.job_detailed_log_format = ->(job) { "override format #{job.strand}" }
88
+ Delayed::Settings.job_detailed_log_format = ->(job) { "override format detailed #{job.strand}" }
89
+ Delayed::Settings.job_short_log_format = ->(_job) { "override format short" }
89
90
  payload = double(perform: nil)
90
91
  job = Delayed::Job.new(payload_object: payload, priority: 25, strand: "test_jobs")
91
92
  short_log_format = subject.log_job(job, :short)
92
- expect(short_log_format).to eq("RSpec::Mocks::Double")
93
+ expect(short_log_format).to eq("RSpec::Mocks::Double override format short")
93
94
  long_format = subject.log_job(job, :long)
94
- expect(long_format).to eq("RSpec::Mocks::Double override format test_jobs")
95
+ expect(long_format).to eq("RSpec::Mocks::Double override format detailed test_jobs")
95
96
  end
96
97
  end
97
98
 
@@ -13,10 +13,10 @@ shared_examples_for "Delayed::Batch" do
13
13
  batch_jobs = Delayed::Job.find_available(5)
14
14
  regular_jobs = Delayed::Job.list_jobs(:future, 5)
15
15
  expect(regular_jobs.size).to eq(1)
16
- expect(regular_jobs.first.batch?).to eq(false)
16
+ expect(regular_jobs.first.batch?).to be(false)
17
17
  expect(batch_jobs.size).to eq(1)
18
18
  batch_job = batch_jobs.first
19
- expect(batch_job.batch?).to eq(true)
19
+ expect(batch_job.batch?).to be(true)
20
20
  expect(batch_job.payload_object.mode).to eq(:serial)
21
21
  expect(batch_job.payload_object.jobs.map do |j|
22
22
  [j.payload_object.object, j.payload_object.method, j.payload_object.args]
@@ -50,7 +50,7 @@ shared_examples_for "Delayed::Batch" do
50
50
  expect(Delayed::Job.jobs_count(:current)).to eq(1)
51
51
 
52
52
  batch_job = Delayed::Job.find_available(1).first
53
- expect(batch_job.batch?).to eq(true)
53
+ expect(batch_job.batch?).to be(true)
54
54
  jobs = batch_job.payload_object.jobs
55
55
  expect(jobs.size).to eq(2)
56
56
  expect(jobs[0]).to be_new_record
@@ -140,7 +140,7 @@ shared_examples_for "random ruby objects" do
140
140
  obj.test_method(7, synchronous: true)
141
141
  expect(obj.ran).to eq([7])
142
142
  obj.ran = nil
143
- expect(obj.ran).to eq(nil)
143
+ expect(obj.ran).to be_nil
144
144
  obj.test_method(8, 9, synchronous: true)
145
145
  expect(obj.ran).to eq([8, 9])
146
146
  end
@@ -233,7 +233,7 @@ shared_examples_for "a backend" do
233
233
  describe "#transfer_lock" do
234
234
  it "works" do
235
235
  job = create_job(locked_by: "worker", locked_at: Delayed::Job.db_time_now)
236
- expect(job.transfer_lock!(from: "worker", to: "worker2")).to eq true
236
+ expect(job.transfer_lock!(from: "worker", to: "worker2")).to be true
237
237
  expect(Delayed::Job.find(job.id).locked_by).to eq "worker2"
238
238
  end
239
239
  end
@@ -243,13 +243,13 @@ shared_examples_for "a backend" do
243
243
  job1 = create_job(strand: "myjobs")
244
244
  job2 = create_job(strand: "myjobs")
245
245
  expect(Delayed::Job.get_and_lock_next_available("w1")).to eq(job1)
246
- expect(Delayed::Job.get_and_lock_next_available("w2")).to eq(nil)
246
+ expect(Delayed::Job.get_and_lock_next_available("w2")).to be_nil
247
247
  job1.destroy
248
248
  # update time since the failed lock pushed it forward
249
249
  job2.run_at = 1.minute.ago
250
250
  job2.save!
251
251
  expect(Delayed::Job.get_and_lock_next_available("w3")).to eq(job2)
252
- expect(Delayed::Job.get_and_lock_next_available("w4")).to eq(nil)
252
+ expect(Delayed::Job.get_and_lock_next_available("w4")).to be_nil
253
253
  end
254
254
 
255
255
  it "fails to lock if an earlier job gets locked" do
@@ -301,7 +301,7 @@ shared_examples_for "a backend" do
301
301
  locked = [Delayed::Job.get_and_lock_next_available("w1"),
302
302
  Delayed::Job.get_and_lock_next_available("w2")]
303
303
  expect(jobs).to eq locked
304
- expect(Delayed::Job.get_and_lock_next_available("w3")).to eq(nil)
304
+ expect(Delayed::Job.get_and_lock_next_available("w3")).to be_nil
305
305
  end
306
306
 
307
307
  it "does not interfere with jobs in other strands" do
@@ -309,7 +309,7 @@ shared_examples_for "a backend" do
309
309
  locked = [Delayed::Job.get_and_lock_next_available("w1"),
310
310
  Delayed::Job.get_and_lock_next_available("w2")]
311
311
  expect(jobs).to eq locked
312
- expect(Delayed::Job.get_and_lock_next_available("w3")).to eq(nil)
312
+ expect(Delayed::Job.get_and_lock_next_available("w3")).to be_nil
313
313
  end
314
314
 
315
315
  it "does not find next jobs when given no priority" do
@@ -317,7 +317,7 @@ shared_examples_for "a backend" do
317
317
  first = Delayed::Job.get_and_lock_next_available("w1", Delayed::Settings.queue, nil, nil)
318
318
  second = Delayed::Job.get_and_lock_next_available("w2", Delayed::Settings.queue, nil, nil)
319
319
  expect(first).to eq jobs.first
320
- expect(second).to eq nil
320
+ expect(second).to be_nil
321
321
  end
322
322
 
323
323
  it "complains if you pass more than one strand-based option" do
@@ -389,7 +389,7 @@ shared_examples_for "a backend" do
389
389
  expect(job1.reload.handler).to include("ErrorJob")
390
390
  end
391
391
 
392
- context "next_in_strand management - deadlocks and race conditions", non_transactional: true do
392
+ context "next_in_strand management - deadlocks and race conditions", non_transactional: true, slow: true do
393
393
  # The following unit tests are fairly slow and non-deterministic. It may be
394
394
  # easier to make them fail quicker and more consistently by adding a random
395
395
  # sleep into the appropriate trigger(s).
@@ -538,11 +538,11 @@ shared_examples_for "a backend" do
538
538
  Delayed::Job.get_and_lock_next_available("w1")
539
539
  @job2 = create_job(singleton: "myjobs")
540
540
 
541
- expect(@job1.reload.next_in_strand).to eq true
542
- expect(@job2.reload.next_in_strand).to eq false
541
+ expect(@job1.reload.next_in_strand).to be true
542
+ expect(@job2.reload.next_in_strand).to be false
543
543
 
544
544
  @job1.destroy
545
- expect(@job2.reload.next_in_strand).to eq true
545
+ expect(@job2.reload.next_in_strand).to be true
546
546
  end
547
547
 
548
548
  it "handles transitions correctly when going from not stranded to stranded" do
@@ -552,13 +552,13 @@ shared_examples_for "a backend" do
552
552
  Delayed::Job.get_and_lock_next_available("w1")
553
553
  @job3 = create_job(singleton: "myjobs", strand: "myjobs2")
554
554
 
555
- expect(@job1.reload.next_in_strand).to eq true
556
- expect(@job2.reload.next_in_strand).to eq true
557
- expect(@job3.reload.next_in_strand).to eq false
555
+ expect(@job1.reload.next_in_strand).to be true
556
+ expect(@job2.reload.next_in_strand).to be true
557
+ expect(@job3.reload.next_in_strand).to be false
558
558
 
559
559
  @job2.destroy
560
- expect(@job1.reload.next_in_strand).to eq true
561
- expect(@job3.reload.next_in_strand).to eq true
560
+ expect(@job1.reload.next_in_strand).to be true
561
+ expect(@job3.reload.next_in_strand).to be true
562
562
  end
563
563
 
564
564
  it "does not violate n_strand=1 constraints when going from not stranded to stranded" do
@@ -568,13 +568,13 @@ shared_examples_for "a backend" do
568
568
  Delayed::Job.get_and_lock_next_available("w1")
569
569
  @job3 = create_job(singleton: "myjobs", strand: "myjobs")
570
570
 
571
- expect(@job1.reload.next_in_strand).to eq true
572
- expect(@job2.reload.next_in_strand).to eq true
573
- expect(@job3.reload.next_in_strand).to eq false
571
+ expect(@job1.reload.next_in_strand).to be true
572
+ expect(@job2.reload.next_in_strand).to be true
573
+ expect(@job3.reload.next_in_strand).to be false
574
574
 
575
575
  @job2.destroy
576
- expect(@job1.reload.next_in_strand).to eq true
577
- expect(@job3.reload.next_in_strand).to eq false
576
+ expect(@job1.reload.next_in_strand).to be true
577
+ expect(@job3.reload.next_in_strand).to be false
578
578
  end
579
579
 
580
580
  it "handles transitions correctly when going from stranded to another strand" do
@@ -582,11 +582,11 @@ shared_examples_for "a backend" do
582
582
  Delayed::Job.get_and_lock_next_available("w1")
583
583
  @job2 = create_job(singleton: "myjobs", strand: "myjobs2")
584
584
 
585
- expect(@job1.reload.next_in_strand).to eq true
586
- expect(@job2.reload.next_in_strand).to eq false
585
+ expect(@job1.reload.next_in_strand).to be true
586
+ expect(@job2.reload.next_in_strand).to be false
587
587
 
588
588
  @job1.destroy
589
- expect(@job2.reload.next_in_strand).to eq true
589
+ expect(@job2.reload.next_in_strand).to be true
590
590
  end
591
591
 
592
592
  it "does not violate n_strand=1 constraints when going from stranded to another strand" do
@@ -596,24 +596,24 @@ shared_examples_for "a backend" do
596
596
  Delayed::Job.get_and_lock_next_available("w1")
597
597
  @job3 = create_job(singleton: "myjobs", strand: "myjobs2")
598
598
 
599
- expect(@job1.reload.next_in_strand).to eq true
600
- expect(@job2.reload.next_in_strand).to eq true
601
- expect(@job3.reload.next_in_strand).to eq false
599
+ expect(@job1.reload.next_in_strand).to be true
600
+ expect(@job2.reload.next_in_strand).to be true
601
+ expect(@job3.reload.next_in_strand).to be false
602
602
 
603
603
  @job2.destroy
604
- expect(@job1.reload.next_in_strand).to eq true
605
- expect(@job3.reload.next_in_strand).to eq false
604
+ expect(@job1.reload.next_in_strand).to be true
605
+ expect(@job3.reload.next_in_strand).to be false
606
606
  end
607
607
 
608
608
  it "creates first as true, and second as false, then transitions to second when deleted" do
609
609
  @job1 = create_job(singleton: "myjobs")
610
610
  Delayed::Job.get_and_lock_next_available("w1")
611
611
  @job2 = create_job(singleton: "myjobs")
612
- expect(@job1.reload.next_in_strand).to eq true
613
- expect(@job2.reload.next_in_strand).to eq false
612
+ expect(@job1.reload.next_in_strand).to be true
613
+ expect(@job2.reload.next_in_strand).to be false
614
614
 
615
615
  @job1.destroy
616
- expect(@job2.reload.next_in_strand).to eq true
616
+ expect(@job2.reload.next_in_strand).to be true
617
617
  end
618
618
 
619
619
  it "when combined with a strand" do
@@ -834,9 +834,9 @@ shared_examples_for "a backend" do
834
834
 
835
835
  it "sets in_delayed_job?" do
836
836
  job = InDelayedJobTest.delay(ignore_transaction: true).check_in_job
837
- expect(Delayed::Job.in_delayed_job?).to eq(false)
837
+ expect(Delayed::Job.in_delayed_job?).to be(false)
838
838
  job.invoke_job
839
- expect(Delayed::Job.in_delayed_job?).to eq(false)
839
+ expect(Delayed::Job.in_delayed_job?).to be(false)
840
840
  end
841
841
 
842
842
  it "fails on job creation if an unsaved AR object is used" do
@@ -244,7 +244,7 @@ shared_examples_for "Delayed::Worker" do
244
244
  end
245
245
 
246
246
  it "is failed if it failed more than Settings.max_attempts times" do
247
- expect(@job.failed_at).to eq(nil)
247
+ expect(@job.failed_at).to be_nil
248
248
  Delayed::Settings.max_attempts.times { @job.reschedule }
249
249
  expect(Delayed::Job.list_jobs(:failed, 100).size).to eq(1)
250
250
  end
@@ -252,7 +252,7 @@ shared_examples_for "Delayed::Worker" do
252
252
  it "is not failed if it failed fewer than Settings.max_attempts times" do
253
253
  (Delayed::Settings.max_attempts - 1).times { @job.reschedule }
254
254
  @job = Delayed::Job.find(@job.id)
255
- expect(@job.failed_at).to eq(nil)
255
+ expect(@job.failed_at).to be_nil
256
256
  end
257
257
 
258
258
  it "is failed if it has expired" do
@@ -396,7 +396,7 @@ shared_examples_for "Delayed::Worker" do
396
396
  expect(@worker).to receive(:exit?).and_return(true)
397
397
  Delayed::Worker.lifecycle.before(:execute) { |w| w == @worker && fired = true }
398
398
  @worker.start
399
- expect(fired).to eq(true)
399
+ expect(fired).to be(true)
400
400
  end
401
401
  end
402
402
 
data/spec/spec_helper.rb CHANGED
@@ -55,14 +55,16 @@ connection_config = {
55
55
  encoding: "utf8",
56
56
  username: ENV["TEST_DB_USERNAME"],
57
57
  database: ENV["TEST_DB_DATABASE"],
58
- min_messages: "notice"
58
+ min_messages: "notice",
59
+ # Ensure the pool is big enough the deadlock tests don't get starved for connections by rails instead
60
+ pool: 20
59
61
  }
60
62
 
61
63
  def migrate(file)
62
64
  ActiveRecord::MigrationContext.new(file, ActiveRecord::SchemaMigration).migrate
63
65
  end
64
66
 
65
- # create the test db if it does not exist, to help out wwtd
67
+ # create the test db if it does not exist
66
68
  ActiveRecord::Base.establish_connection(connection_config.merge(database: "postgres"))
67
69
  begin
68
70
  ActiveRecord::Base.connection.create_database(connection_config[:database])
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inst-jobs
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.9
4
+ version: 3.0.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cody Cutrer
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2022-02-23 00:00:00.000000000 Z
13
+ date: 2022-04-05 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -32,14 +32,14 @@ dependencies:
32
32
  requirements:
33
33
  - - "~>"
34
34
  - !ruby/object:Gem::Version
35
- version: '0.4'
35
+ version: 0.4.4
36
36
  type: :runtime
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
40
  - - "~>"
41
41
  - !ruby/object:Gem::Version
42
- version: '0.4'
42
+ version: 0.4.4
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: activesupport
45
45
  requirement: !ruby/object:Gem::Requirement
@@ -410,20 +410,6 @@ dependencies:
410
410
  - - ">="
411
411
  - !ruby/object:Gem::Version
412
412
  version: '0'
413
- - !ruby/object:Gem::Dependency
414
- name: wwtd
415
- requirement: !ruby/object:Gem::Requirement
416
- requirements:
417
- - - "~>"
418
- - !ruby/object:Gem::Version
419
- version: 1.4.0
420
- type: :development
421
- prerelease: false
422
- version_requirements: !ruby/object:Gem::Requirement
423
- requirements:
424
- - - "~>"
425
- - !ruby/object:Gem::Version
426
- version: 1.4.0
427
413
  description:
428
414
  email:
429
415
  - cody@instructure.com
@@ -473,6 +459,7 @@ files:
473
459
  - db/migrate/20220128084800_update_insert_trigger_for_singleton_unique_constraint_change.rb
474
460
  - db/migrate/20220128084900_update_delete_trigger_for_singleton_unique_constraint_change.rb
475
461
  - db/migrate/20220203063200_remove_old_singleton_index.rb
462
+ - db/migrate/20220328152900_add_failed_jobs_indicies.rb
476
463
  - exe/inst_jobs
477
464
  - lib/delayed/backend/active_record.rb
478
465
  - lib/delayed/backend/base.rb
@@ -538,7 +525,8 @@ files:
538
525
  - spec/spec_helper.rb
539
526
  homepage: https://github.com/instructure/inst-jobs
540
527
  licenses: []
541
- metadata: {}
528
+ metadata:
529
+ rubygems_mfa_required: 'true'
542
530
  post_install_message:
543
531
  rdoc_options: []
544
532
  require_paths:
@@ -554,7 +542,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
554
542
  - !ruby/object:Gem::Version
555
543
  version: '0'
556
544
  requirements: []
557
- rubygems_version: 3.1.4
545
+ rubygems_version: 3.1.6
558
546
  signing_key:
559
547
  specification_version: 4
560
548
  summary: Instructure-maintained fork of delayed_job