inst-jobs 3.1.16 → 3.1.18
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/backend/active_record.rb +53 -33
- data/lib/delayed/backend/base.rb +3 -9
- data/lib/delayed/batch.rb +3 -3
- data/lib/delayed/daemon.rb +4 -4
- data/lib/delayed/engine.rb +7 -0
- data/lib/delayed/lifecycle.rb +13 -13
- data/lib/delayed/logging.rb +1 -3
- data/lib/delayed/message_sending.rb +9 -9
- data/lib/delayed/periodic.rb +2 -2
- data/lib/delayed/pool.rb +3 -11
- data/lib/delayed/server.rb +1 -7
- data/lib/delayed/settings.rb +1 -1
- data/lib/delayed/testing.rb +2 -2
- data/lib/delayed/version.rb +1 -1
- data/lib/delayed/work_queue/parent_process/server.rb +6 -10
- data/lib/delayed/work_queue/parent_process.rb +1 -1
- data/lib/delayed/worker/consul_health_check.rb +1 -1
- data/lib/delayed/worker/health_check.rb +1 -1
- data/lib/delayed/worker/process_helper.rb +2 -2
- data/lib/delayed/worker.rb +0 -3
- metadata +31 -32
- data/lib/delayed/rails_reloader_plugin.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 43f35fb4227a589dfb6d6d50c0b42ca44bdc83572ba7ac250d1ea887b8f4d558
|
4
|
+
data.tar.gz: 9f100f92e8bbe68961cbec784d04a12c9457c36a21c13337dcbda10d5d38f985
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 489b588fbce6951d6b965d850c255a2bba887e2423a977b41a0a6f54142c569eaa96aa04a2e38f50114ff1c57a5e79cc83121cce20794f3ddfb289c15144c143
|
7
|
+
data.tar.gz: 893782fd155cfb9a83575597845e9500fc9199fa042f08bc087cc42a63b0630aef37bb640b865c4649b69478a57944b63ff4cd4ec2c2a154df9885f2e5d5d722
|
@@ -28,30 +28,31 @@ module Delayed
|
|
28
28
|
attr_accessor :enqueue_result
|
29
29
|
|
30
30
|
scope :next_in_strand_order, -> { order(:strand_order_override, :id) }
|
31
|
+
scope :locked, -> { where.not(locked_by: nil) }
|
32
|
+
scope :not_locked, -> { where(locked_by: nil) }
|
33
|
+
scope :prefetched, -> { where(arel_table[:locked_by].matches("prefetch%")) }
|
31
34
|
|
32
35
|
def self.reconnect!
|
33
|
-
|
34
|
-
::ActiveRecord::Base.connection_handler.clear_all_connections!
|
35
|
-
else
|
36
|
-
::ActiveRecord::Base.connection_handler.clear_all_connections!(nil)
|
37
|
-
end
|
36
|
+
::ActiveRecord::Base.connection_handler.clear_all_connections!(nil)
|
38
37
|
end
|
39
38
|
|
40
39
|
class << self
|
41
|
-
def create(attributes, &
|
40
|
+
def create(attributes, &)
|
42
41
|
on_conflict = attributes.delete(:on_conflict)
|
43
42
|
# modified from ActiveRecord::Persistence.create and ActiveRecord::Persistence#_insert_record
|
44
|
-
job = new(attributes, &
|
45
|
-
job.single_step_create(on_conflict:
|
43
|
+
job = new(attributes, &)
|
44
|
+
job.single_step_create(on_conflict:)
|
46
45
|
end
|
47
46
|
|
48
47
|
def attempt_advisory_lock(lock_name)
|
49
48
|
fn_name = connection.quote_table_name("half_md5_as_bigint")
|
49
|
+
lock_name = connection.quote_string(lock_name)
|
50
50
|
connection.select_value("SELECT pg_try_advisory_xact_lock(#{fn_name}('#{lock_name}'));")
|
51
51
|
end
|
52
52
|
|
53
53
|
def advisory_lock(lock_name)
|
54
54
|
fn_name = connection.quote_table_name("half_md5_as_bigint")
|
55
|
+
lock_name = connection.quote_string(lock_name)
|
55
56
|
connection.execute("SELECT pg_advisory_xact_lock(#{fn_name}('#{lock_name}'));")
|
56
57
|
end
|
57
58
|
end
|
@@ -68,21 +69,12 @@ module Delayed
|
|
68
69
|
_write_attribute(column, current_time) unless attribute_present?(column)
|
69
70
|
end
|
70
71
|
|
71
|
-
attribute_names =
|
72
|
-
attribute_names_for_partial_writes
|
73
|
-
else
|
74
|
-
attribute_names_for_partial_inserts
|
75
|
-
end
|
72
|
+
attribute_names = attribute_names_for_partial_inserts
|
76
73
|
attribute_names = attributes_for_create(attribute_names)
|
77
74
|
values = attributes_with_values(attribute_names)
|
78
75
|
|
79
|
-
im =
|
80
|
-
|
81
|
-
else
|
82
|
-
im = Arel::InsertManager.new(self.class.arel_table)
|
83
|
-
im.insert(values.transform_keys { |name| self.class.arel_table[name] })
|
84
|
-
im
|
85
|
-
end
|
76
|
+
im = Arel::InsertManager.new(self.class.arel_table)
|
77
|
+
im.insert(values.transform_keys { |name| self.class.arel_table[name] })
|
86
78
|
|
87
79
|
lock_and_insert = values["strand"] && instance_of?(Job)
|
88
80
|
# can't use prepared statements if we're combining multiple statemenets
|
@@ -118,7 +110,7 @@ module Delayed
|
|
118
110
|
# but we don't need to lock when inserting into Delayed::Failed
|
119
111
|
if values["strand"] && instance_of?(Job)
|
120
112
|
fn_name = connection.quote_table_name("half_md5_as_bigint")
|
121
|
-
quoted_strand = connection.quote(
|
113
|
+
quoted_strand = connection.quote(values["strand"].value)
|
122
114
|
sql = "SELECT pg_advisory_xact_lock(#{fn_name}(#{quoted_strand})); #{sql}"
|
123
115
|
end
|
124
116
|
result = connection.execute(sql, "#{self.class} Create")
|
@@ -223,7 +215,7 @@ module Delayed
|
|
223
215
|
end
|
224
216
|
|
225
217
|
def self.strand_size(strand)
|
226
|
-
where(strand:
|
218
|
+
where(strand:).count
|
227
219
|
end
|
228
220
|
|
229
221
|
def self.running_jobs
|
@@ -248,7 +240,7 @@ module Delayed
|
|
248
240
|
|
249
241
|
if %w[current future].include?(flavor.to_s)
|
250
242
|
queue = query.presence || Delayed::Settings.queue
|
251
|
-
scope = scope.where(queue:
|
243
|
+
scope = scope.where(queue:)
|
252
244
|
end
|
253
245
|
|
254
246
|
scope
|
@@ -344,16 +336,16 @@ module Delayed
|
|
344
336
|
job_count = 0
|
345
337
|
new_strand = "tmp_strand_#{SecureRandom.alphanumeric(16)}"
|
346
338
|
::Delayed::Job.transaction do
|
347
|
-
job_count = job_scope.update_all(strand: new_strand, max_concurrent
|
339
|
+
job_count = job_scope.update_all(strand: new_strand, max_concurrent:, next_in_strand: false)
|
348
340
|
::Delayed::Job.where(strand: new_strand).order(:id).limit(max_concurrent).update_all(next_in_strand: true)
|
349
341
|
end
|
350
342
|
|
351
343
|
[job_count, new_strand]
|
352
344
|
end
|
353
345
|
|
354
|
-
def self.maybe_silence_periodic_log(&
|
346
|
+
def self.maybe_silence_periodic_log(&)
|
355
347
|
if Settings.silence_periodic_log
|
356
|
-
::ActiveRecord::Base.logger.silence(&
|
348
|
+
::ActiveRecord::Base.logger.silence(&)
|
357
349
|
else
|
358
350
|
yield
|
359
351
|
end
|
@@ -366,7 +358,6 @@ module Delayed
|
|
366
358
|
prefetch: 0,
|
367
359
|
prefetch_owner: nil,
|
368
360
|
forced_latency: nil)
|
369
|
-
|
370
361
|
check_queue(queue)
|
371
362
|
check_priorities(min_priority, max_priority)
|
372
363
|
|
@@ -384,7 +375,7 @@ module Delayed
|
|
384
375
|
target_jobs = all_available(queue,
|
385
376
|
min_priority,
|
386
377
|
max_priority,
|
387
|
-
forced_latency:
|
378
|
+
forced_latency:)
|
388
379
|
.limit(effective_worker_names.length + prefetch)
|
389
380
|
.lock(lock)
|
390
381
|
jobs_with_row_number = all.from(target_jobs)
|
@@ -409,7 +400,36 @@ module Delayed
|
|
409
400
|
RETURNING #{quoted_table_name}.*
|
410
401
|
SQL
|
411
402
|
|
412
|
-
|
403
|
+
begin
|
404
|
+
jobs = find_by_sql(query)
|
405
|
+
rescue ::ActiveRecord::RecordNotUnique => e
|
406
|
+
# if we got a unique violation on a singleton, it's because next_in_strand
|
407
|
+
# somehow got set to true on the non-running job when there is a running
|
408
|
+
# job. AFAICT this is not possible from inst-jobs itself, but has happened
|
409
|
+
# in production - either due to manual manipulation of jobs, or possibly
|
410
|
+
# a process in something like switchman-inst-jobs
|
411
|
+
raise unless e.message.include?('"index_delayed_jobs_on_singleton_running"')
|
412
|
+
|
413
|
+
# just repair the "strand"
|
414
|
+
singleton = e.message.match(/Key \(singleton\)=\((.+)\) already exists.$/)[1]
|
415
|
+
raise unless singleton
|
416
|
+
|
417
|
+
transaction do
|
418
|
+
# very conservatively lock the locked job, so that it won't unlock from underneath us and
|
419
|
+
# leave an orphaned strand
|
420
|
+
advisory_lock("singleton:#{singleton}")
|
421
|
+
locked_jobs = where(singleton:).where.not(locked_by: nil).lock.pluck(:id)
|
422
|
+
# if it's already gone, then we're good and should be able to just retry
|
423
|
+
if locked_jobs.length == 1
|
424
|
+
updated = where(singleton:, next_in_strand: true)
|
425
|
+
.where(locked_by: nil)
|
426
|
+
.update_all(next_in_strand: false)
|
427
|
+
raise if updated.zero?
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
431
|
+
retry
|
432
|
+
end
|
413
433
|
# because this is an atomic query, we don't have to return more jobs than we needed
|
414
434
|
# to try and lock them, nor is there a possibility we need to try again because
|
415
435
|
# all of the jobs we tried to lock had already been locked by someone else
|
@@ -468,8 +488,8 @@ module Delayed
|
|
468
488
|
check_queue(queue)
|
469
489
|
check_priorities(min_priority, max_priority)
|
470
490
|
|
471
|
-
ready_to_run(forced_latency:
|
472
|
-
.where(priority: min_priority..max_priority, queue:
|
491
|
+
ready_to_run(forced_latency:)
|
492
|
+
.where(priority: min_priority..max_priority, queue:)
|
473
493
|
.by_priority
|
474
494
|
end
|
475
495
|
|
@@ -482,7 +502,7 @@ module Delayed
|
|
482
502
|
on_conflict = options.delete(:on_conflict) || :use_earliest
|
483
503
|
|
484
504
|
transaction_for_singleton(singleton, on_conflict) do
|
485
|
-
job = where(strand
|
505
|
+
job = where(strand:, locked_at: nil).next_in_strand_order.first
|
486
506
|
new_job = new(options)
|
487
507
|
if job
|
488
508
|
new_job.initialize_defaults
|
@@ -616,7 +636,7 @@ module Delayed
|
|
616
636
|
self.table_name = :failed_jobs
|
617
637
|
|
618
638
|
def self.cleanup_old_jobs(before_date, batch_size: 10_000)
|
619
|
-
where(
|
639
|
+
where(failed_at: ...before_date).in_batches(of: batch_size).delete_all
|
620
640
|
end
|
621
641
|
|
622
642
|
def requeue!
|
data/lib/delayed/backend/base.rb
CHANGED
@@ -40,7 +40,6 @@ module Delayed
|
|
40
40
|
n_strand: nil,
|
41
41
|
max_attempts: Delayed::Settings.max_attempts,
|
42
42
|
**kwargs)
|
43
|
-
|
44
43
|
unless object.respond_to?(:perform)
|
45
44
|
raise ArgumentError, "Cannot enqueue items which do not respond to perform"
|
46
45
|
end
|
@@ -307,19 +306,14 @@ module Delayed
|
|
307
306
|
|
308
307
|
# Moved into its own method so that new_relic can trace it.
|
309
308
|
def invoke_job
|
309
|
+
ActiveSupport::ExecutionContext[:job] = self
|
310
310
|
Delayed::Worker.lifecycle.run_callbacks(:invoke_job, self) do
|
311
311
|
Delayed::Job.in_delayed_job = true
|
312
312
|
begin
|
313
313
|
payload_object.perform
|
314
314
|
ensure
|
315
315
|
Delayed::Job.in_delayed_job = false
|
316
|
-
unless Rails.env.test?
|
317
|
-
if Rails.version < "6.1"
|
318
|
-
::ActiveRecord::Base.clear_active_connections!
|
319
|
-
else
|
320
|
-
::ActiveRecord::Base.clear_active_connections!(nil)
|
321
|
-
end
|
322
|
-
end
|
316
|
+
::ActiveRecord::Base.connection_handler.clear_active_connections!(nil) unless Rails.env.test?
|
323
317
|
end
|
324
318
|
end
|
325
319
|
end
|
@@ -374,7 +368,7 @@ module Delayed
|
|
374
368
|
|
375
369
|
private
|
376
370
|
|
377
|
-
PARSE_OBJECT_FROM_YAML = %r{!ruby/\w+:([^\s]+)}
|
371
|
+
PARSE_OBJECT_FROM_YAML = %r{!ruby/\w+:([^\s]+)}
|
378
372
|
private_constant :PARSE_OBJECT_FROM_YAML
|
379
373
|
|
380
374
|
def deserialize(source)
|
data/lib/delayed/batch.rb
CHANGED
@@ -25,8 +25,8 @@ module Delayed
|
|
25
25
|
end
|
26
26
|
|
27
27
|
class << self
|
28
|
-
def serial_batch(opts = {}, &
|
29
|
-
prepare_batches(:serial, opts, &
|
28
|
+
def serial_batch(opts = {}, &)
|
29
|
+
prepare_batches(:serial, opts, &)
|
30
30
|
end
|
31
31
|
|
32
32
|
private
|
@@ -51,7 +51,7 @@ module Delayed
|
|
51
51
|
payload_object = args.delete(:payload_object)
|
52
52
|
Delayed::Job.enqueue(payload_object, **args)
|
53
53
|
else
|
54
|
-
Delayed::Job.enqueue(Delayed::Batch::PerformableBatch.new(mode, batch), **enqueue_args
|
54
|
+
Delayed::Job.enqueue(Delayed::Batch::PerformableBatch.new(mode, batch), **enqueue_args, **batch_args)
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end
|
data/lib/delayed/daemon.rb
CHANGED
@@ -43,7 +43,7 @@ module Delayed
|
|
43
43
|
# it somewhere useful
|
44
44
|
last_ditch_logfile = Settings.last_ditch_logfile || "log/delayed_job.log"
|
45
45
|
last_ditch_logfile = Settings.expand_rails_path(last_ditch_logfile) if last_ditch_logfile[0] != "|"
|
46
|
-
$stdin.reopen(
|
46
|
+
$stdin.reopen(File::NULL)
|
47
47
|
$stdout.reopen(open(last_ditch_logfile, "a")) # rubocop:disable Security/Open
|
48
48
|
$stderr.reopen($stdout)
|
49
49
|
$stdout.sync = $stderr.sync = true
|
@@ -51,7 +51,7 @@ module Delayed
|
|
51
51
|
|
52
52
|
# stop the currently running daemon (not this current process, the one in the pid_file)
|
53
53
|
def stop(kill: false, pid: self.pid)
|
54
|
-
alive = status(pid
|
54
|
+
alive = status(pid:, print: false)
|
55
55
|
if alive == :running || (kill && alive == :draining)
|
56
56
|
puts "Stopping pool #{pid}..."
|
57
57
|
signal = kill ? "TERM" : "QUIT"
|
@@ -68,9 +68,9 @@ module Delayed
|
|
68
68
|
|
69
69
|
def wait(kill)
|
70
70
|
if kill
|
71
|
-
sleep(0.5) while status(pid
|
71
|
+
sleep(0.5) while status(pid:, print: false)
|
72
72
|
else
|
73
|
-
sleep(0.5) while status(pid
|
73
|
+
sleep(0.5) while status(pid:, print: false) == :running
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
data/lib/delayed/engine.rb
CHANGED
@@ -2,5 +2,12 @@
|
|
2
2
|
|
3
3
|
module Delayed
|
4
4
|
class Engine < ::Rails::Engine
|
5
|
+
initializer "delayed_job.set_reloader_hook" do |app|
|
6
|
+
Delayed::Worker.lifecycle.around(:perform) do |worker, job, &block|
|
7
|
+
app.reloader.wrap(source: "application.delayed_job") do
|
8
|
+
block.call(worker, job)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
5
12
|
end
|
6
13
|
end
|
data/lib/delayed/lifecycle.rb
CHANGED
@@ -30,34 +30,34 @@ module Delayed
|
|
30
30
|
Delayed::Worker.plugins.each(&:reset!)
|
31
31
|
end
|
32
32
|
|
33
|
-
def before(event, &
|
34
|
-
add(:before, event, &
|
33
|
+
def before(event, &)
|
34
|
+
add(:before, event, &)
|
35
35
|
end
|
36
36
|
|
37
|
-
def after(event, &
|
38
|
-
add(:after, event, &
|
37
|
+
def after(event, &)
|
38
|
+
add(:after, event, &)
|
39
39
|
end
|
40
40
|
|
41
|
-
def around(event, &
|
42
|
-
add(:around, event, &
|
41
|
+
def around(event, &)
|
42
|
+
add(:around, event, &)
|
43
43
|
end
|
44
44
|
|
45
|
-
def run_callbacks(event, *args, &
|
45
|
+
def run_callbacks(event, *args, &)
|
46
46
|
missing_callback(event) unless @callbacks.key?(event)
|
47
47
|
|
48
48
|
unless EVENTS[event].size == args.size
|
49
49
|
raise ArgumentError, "Callback #{event} expects #{EVENTS[event].size} parameter(s): #{EVENTS[event].join(", ")}"
|
50
50
|
end
|
51
51
|
|
52
|
-
@callbacks[event].execute(*args, &
|
52
|
+
@callbacks[event].execute(*args, &)
|
53
53
|
end
|
54
54
|
|
55
55
|
private
|
56
56
|
|
57
|
-
def add(type, event, &
|
57
|
+
def add(type, event, &)
|
58
58
|
missing_callback(event) unless @callbacks.key?(event)
|
59
59
|
|
60
|
-
@callbacks[event].add(type, &
|
60
|
+
@callbacks[event].add(type, &)
|
61
61
|
end
|
62
62
|
|
63
63
|
def missing_callback(event)
|
@@ -74,12 +74,12 @@ module Delayed
|
|
74
74
|
@around = ->(*args, &block) { block.call(*args) }
|
75
75
|
end
|
76
76
|
|
77
|
-
def execute(*args, &
|
77
|
+
def execute(*args, &)
|
78
78
|
@before.each { |c| c.call(*args) }
|
79
|
-
result = @around.call(*args, &
|
79
|
+
result = @around.call(*args, &)
|
80
80
|
@after.each do |c|
|
81
81
|
if c.arity == args.length + 1 # don't fail for methods that don't define `result:`
|
82
|
-
c.call(*args, result:
|
82
|
+
c.call(*args, result:)
|
83
83
|
else
|
84
84
|
c.call(*args)
|
85
85
|
end
|
data/lib/delayed/logging.rb
CHANGED
@@ -56,10 +56,10 @@ module Delayed
|
|
56
56
|
connection.after_transaction_commit do
|
57
57
|
::Delayed::Job.enqueue(::Delayed::PerformableMethod.new(@object,
|
58
58
|
method,
|
59
|
-
args
|
60
|
-
kwargs
|
61
|
-
on_failure
|
62
|
-
on_permanent_failure
|
59
|
+
args:,
|
60
|
+
kwargs:,
|
61
|
+
on_failure:,
|
62
|
+
on_permanent_failure:,
|
63
63
|
sender: @sender),
|
64
64
|
**@enqueue_args)
|
65
65
|
end
|
@@ -69,10 +69,10 @@ module Delayed
|
|
69
69
|
|
70
70
|
result = ::Delayed::Job.enqueue(::Delayed::PerformableMethod.new(@object,
|
71
71
|
method,
|
72
|
-
args
|
73
|
-
kwargs
|
74
|
-
on_failure
|
75
|
-
on_permanent_failure
|
72
|
+
args:,
|
73
|
+
kwargs:,
|
74
|
+
on_failure:,
|
75
|
+
on_permanent_failure:,
|
76
76
|
sender: @sender),
|
77
77
|
**@enqueue_args)
|
78
78
|
result = nil unless ignore_transaction
|
@@ -101,7 +101,7 @@ module Delayed
|
|
101
101
|
|
102
102
|
sender ||= __calculate_sender_for_delay
|
103
103
|
|
104
|
-
DelayProxy.new(self, sender
|
104
|
+
DelayProxy.new(self, sender:, **enqueue_args)
|
105
105
|
end
|
106
106
|
|
107
107
|
def __calculate_sender_for_delay
|
data/lib/delayed/periodic.rb
CHANGED
@@ -15,7 +15,7 @@ module Delayed
|
|
15
15
|
self.overrides = {}
|
16
16
|
|
17
17
|
def self.add_overrides(overrides)
|
18
|
-
overrides.
|
18
|
+
overrides.each_value do |cron_line|
|
19
19
|
# throws error if the line is malformed
|
20
20
|
Fugit.do_parse_cron(cron_line)
|
21
21
|
end
|
@@ -45,7 +45,7 @@ module Delayed
|
|
45
45
|
# make sure all periodic jobs are scheduled for their next run in the job queue
|
46
46
|
# this auditing should run on the strand
|
47
47
|
def self.perform_audit!
|
48
|
-
scheduled.
|
48
|
+
scheduled.each_value(&:enqueue)
|
49
49
|
end
|
50
50
|
|
51
51
|
def initialize(name, cron_line, job_args, block)
|
data/lib/delayed/pool.rb
CHANGED
@@ -69,19 +69,11 @@ module Delayed
|
|
69
69
|
say "Unlocked #{unlocked_jobs} orphaned jobs" if unlocked_jobs.positive?
|
70
70
|
return if Rails.env.test?
|
71
71
|
|
72
|
-
|
73
|
-
ActiveRecord::Base.connection_handler.clear_all_connections!
|
74
|
-
else
|
75
|
-
ActiveRecord::Base.connection_handler.clear_all_connections!(nil)
|
76
|
-
end
|
72
|
+
ActiveRecord::Base.connection_handler.clear_all_connections!(nil)
|
77
73
|
end
|
78
74
|
|
79
75
|
def spawn_all_workers
|
80
|
-
|
81
|
-
ActiveRecord::Base.connection_handler.clear_all_connections!
|
82
|
-
else
|
83
|
-
ActiveRecord::Base.connection_handler.clear_all_connections!(nil)
|
84
|
-
end
|
76
|
+
ActiveRecord::Base.connection_handler.clear_all_connections!(nil)
|
85
77
|
|
86
78
|
if @config[:work_queue] == "parent_process"
|
87
79
|
@work_queue = WorkQueue::ParentProcess.new
|
@@ -97,7 +89,7 @@ module Delayed
|
|
97
89
|
parent_pid = Process.pid
|
98
90
|
pid = fork_with_reconnects do
|
99
91
|
$0 = "delayed_jobs_work_queue#{Settings.pool_procname_suffix}"
|
100
|
-
@work_queue.server(parent_pid:
|
92
|
+
@work_queue.server(parent_pid:).run
|
101
93
|
end
|
102
94
|
workers[pid] = :work_queue
|
103
95
|
end
|
data/lib/delayed/server.rb
CHANGED
@@ -37,13 +37,7 @@ module Delayed
|
|
37
37
|
|
38
38
|
# Release any used connections back to the pool
|
39
39
|
after do
|
40
|
-
if using_active_record?
|
41
|
-
if Rails.version < "6.1"
|
42
|
-
::ActiveRecord::Base.clear_active_connections!
|
43
|
-
else
|
44
|
-
::ActiveRecord::Base.clear_active_connections!(nil)
|
45
|
-
end
|
46
|
-
end
|
40
|
+
::ActiveRecord::Base.connection_handler.clear_active_connections!(nil) if using_active_record?
|
47
41
|
end
|
48
42
|
|
49
43
|
configure :development do
|
data/lib/delayed/settings.rb
CHANGED
@@ -88,7 +88,7 @@ module Delayed
|
|
88
88
|
|
89
89
|
def apply_worker_config!(config)
|
90
90
|
SETTINGS.each do |setting|
|
91
|
-
send("#{setting}=", config[setting.to_s]) if config.key?(setting.to_s)
|
91
|
+
send(:"#{setting}=", config[setting.to_s]) if config.key?(setting.to_s)
|
92
92
|
end
|
93
93
|
if config.key?("parent_process_client_timeout")
|
94
94
|
parent_process.client_timeout = config["parent_process_client_timeout"]
|
data/lib/delayed/testing.rb
CHANGED
data/lib/delayed/version.rb
CHANGED
@@ -75,7 +75,7 @@ module Delayed
|
|
75
75
|
readable, = IO.select(handles, nil, nil, timeout)
|
76
76
|
readable&.each { |s| handle_read(s) }
|
77
77
|
Delayed::Worker.lifecycle.run_callbacks(:check_for_work, self) do
|
78
|
-
check_for_work(forced_latency:
|
78
|
+
check_for_work(forced_latency:)
|
79
79
|
end
|
80
80
|
unlock_timed_out_prefetched_jobs
|
81
81
|
end
|
@@ -159,8 +159,8 @@ module Delayed
|
|
159
159
|
worker_config[:min_priority],
|
160
160
|
worker_config[:max_priority],
|
161
161
|
prefetch: (Settings.fetch_batch_size * (worker_config[:workers] || 1)) - recipients.length,
|
162
|
-
prefetch_owner
|
163
|
-
forced_latency:
|
162
|
+
prefetch_owner:,
|
163
|
+
forced_latency:
|
164
164
|
)
|
165
165
|
logger.debug(
|
166
166
|
"Fetched and locked #{response.values.flatten.size} new jobs for workers (#{response.keys.join(", ")})."
|
@@ -226,11 +226,7 @@ module Delayed
|
|
226
226
|
|
227
227
|
# otherwise just reconnect and let it retry
|
228
228
|
logger.warn("failed to unlock prefetched jobs - connection terminated; skipping for now")
|
229
|
-
|
230
|
-
::Delayed::Job.clear_all_connections!
|
231
|
-
else
|
232
|
-
::Delayed::Job.clear_all_connections!(nil)
|
233
|
-
end
|
229
|
+
::Delayed::Job.clear_all_connections!(nil)
|
234
230
|
end
|
235
231
|
end
|
236
232
|
|
@@ -274,8 +270,8 @@ module Delayed
|
|
274
270
|
@parent_pid && @parent_pid != Process.ppid
|
275
271
|
end
|
276
272
|
|
277
|
-
def client_timeout(&
|
278
|
-
Timeout.timeout(@client_timeout, &
|
273
|
+
def client_timeout(&)
|
274
|
+
Timeout.timeout(@client_timeout, &)
|
279
275
|
end
|
280
276
|
|
281
277
|
ClientState = Struct.new(:working, :socket, :name)
|
@@ -43,7 +43,7 @@ module Delayed
|
|
43
43
|
# The unix_server_socket method takes care of cleaning up any existing
|
44
44
|
# socket for us if the work queue process dies and is restarted.
|
45
45
|
listen_socket = Socket.unix_server_socket(@server_address)
|
46
|
-
Server.new(listen_socket, parent_pid
|
46
|
+
Server.new(listen_socket, parent_pid:, config: @config)
|
47
47
|
end
|
48
48
|
|
49
49
|
def client
|
@@ -22,7 +22,7 @@ module Delayed
|
|
22
22
|
if config.keys.any? { |k| CONSUL_CONFIG_KEYS.include?(k) }
|
23
23
|
consul_config = Diplomat::Configuration.new.tap do |conf|
|
24
24
|
CONSUL_CONFIG_KEYS.each do |key|
|
25
|
-
conf.send("#{key}=", config[key]) if config[key]
|
25
|
+
conf.send(:"#{key}=", config[key]) if config[key]
|
26
26
|
end
|
27
27
|
end
|
28
28
|
@service_client = Diplomat::Service.new(configuration: consul_config)
|
@@ -19,7 +19,7 @@ module Delayed
|
|
19
19
|
klass = @subclasses.find { |sc| sc.type_name == type }
|
20
20
|
raise ArgumentError, "Unable to build a HealthCheck for type #{type}" unless klass
|
21
21
|
|
22
|
-
klass.new(worker_name
|
22
|
+
klass.new(worker_name:, config:)
|
23
23
|
end
|
24
24
|
|
25
25
|
def reschedule_abandoned_jobs
|
@@ -9,7 +9,7 @@ module Delayed
|
|
9
9
|
ALIVE_CHECK_LINUX = '[ -d "/proc/$WORKER_PID" ]'
|
10
10
|
ALIVE_CHECK_MAC = "ps -p $WORKER_PID > /dev/null"
|
11
11
|
ALIVE_CHECK = RUBY_PLATFORM.include?("darwin") ? ALIVE_CHECK_MAC : ALIVE_CHECK_LINUX
|
12
|
-
SCRIPT_TEMPLATE = <<~SH
|
12
|
+
SCRIPT_TEMPLATE = <<~SH.freeze
|
13
13
|
WORKER_PID="%{pid}" # an example, filled from ruby when the check is created
|
14
14
|
ORIGINAL_MTIME="%{mtime}" # an example, filled from ruby when the check is created
|
15
15
|
|
@@ -37,7 +37,7 @@ module Delayed
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def self.check_script(pid, mtime)
|
40
|
-
format(SCRIPT_TEMPLATE, { pid
|
40
|
+
format(SCRIPT_TEMPLATE, { pid:, mtime: })
|
41
41
|
end
|
42
42
|
|
43
43
|
def self.process_is_still_running?(pid, mtime)
|
data/lib/delayed/worker.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "delayed/rails_reloader_plugin"
|
4
|
-
|
5
3
|
module Delayed
|
6
4
|
class TimeoutError < RuntimeError; end
|
7
5
|
|
@@ -73,7 +71,6 @@ module Delayed
|
|
73
71
|
|
74
72
|
@signal_queue = []
|
75
73
|
|
76
|
-
plugins << Delayed::RailsReloaderPlugin
|
77
74
|
plugins.each(&:inject!)
|
78
75
|
end
|
79
76
|
|
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inst-jobs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.1.
|
4
|
+
version: 3.1.18
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cody Cutrer
|
8
8
|
- Ethan Vizitei
|
9
9
|
- Jacob Burroughs
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2025-03-13 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -18,14 +18,14 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ">="
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: '
|
21
|
+
version: '7.0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - ">="
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: '
|
28
|
+
version: '7.0'
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: activerecord-pg-extensions
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
@@ -46,14 +46,14 @@ dependencies:
|
|
46
46
|
requirements:
|
47
47
|
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: '
|
49
|
+
version: '7.0'
|
50
50
|
type: :runtime
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
54
|
- - ">="
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version: '
|
56
|
+
version: '7.0'
|
57
57
|
- !ruby/object:Gem::Dependency
|
58
58
|
name: after_transaction_commit
|
59
59
|
requirement: !ruby/object:Gem::Requirement
|
@@ -131,21 +131,21 @@ dependencies:
|
|
131
131
|
- !ruby/object:Gem::Version
|
132
132
|
version: '0'
|
133
133
|
- !ruby/object:Gem::Dependency
|
134
|
-
name:
|
134
|
+
name: database_cleaner
|
135
135
|
requirement: !ruby/object:Gem::Requirement
|
136
136
|
requirements:
|
137
|
-
- - "
|
137
|
+
- - "~>"
|
138
138
|
- !ruby/object:Gem::Version
|
139
|
-
version: '0'
|
139
|
+
version: '2.0'
|
140
140
|
type: :development
|
141
141
|
prerelease: false
|
142
142
|
version_requirements: !ruby/object:Gem::Requirement
|
143
143
|
requirements:
|
144
|
-
- - "
|
144
|
+
- - "~>"
|
145
145
|
- !ruby/object:Gem::Version
|
146
|
-
version: '0'
|
146
|
+
version: '2.0'
|
147
147
|
- !ruby/object:Gem::Dependency
|
148
|
-
name: database_cleaner
|
148
|
+
name: database_cleaner-active_record
|
149
149
|
requirement: !ruby/object:Gem::Requirement
|
150
150
|
requirements:
|
151
151
|
- - "~>"
|
@@ -159,19 +159,19 @@ dependencies:
|
|
159
159
|
- !ruby/object:Gem::Version
|
160
160
|
version: '2.0'
|
161
161
|
- !ruby/object:Gem::Dependency
|
162
|
-
name:
|
162
|
+
name: debug
|
163
163
|
requirement: !ruby/object:Gem::Requirement
|
164
164
|
requirements:
|
165
|
-
- - "
|
165
|
+
- - ">="
|
166
166
|
- !ruby/object:Gem::Version
|
167
|
-
version: '
|
167
|
+
version: '0'
|
168
168
|
type: :development
|
169
169
|
prerelease: false
|
170
170
|
version_requirements: !ruby/object:Gem::Requirement
|
171
171
|
requirements:
|
172
|
-
- - "
|
172
|
+
- - ">="
|
173
173
|
- !ruby/object:Gem::Version
|
174
|
-
version: '
|
174
|
+
version: '0'
|
175
175
|
- !ruby/object:Gem::Dependency
|
176
176
|
name: diplomat
|
177
177
|
requirement: !ruby/object:Gem::Requirement
|
@@ -187,7 +187,7 @@ dependencies:
|
|
187
187
|
- !ruby/object:Gem::Version
|
188
188
|
version: 2.6.3
|
189
189
|
- !ruby/object:Gem::Dependency
|
190
|
-
name:
|
190
|
+
name: mutex_m
|
191
191
|
requirement: !ruby/object:Gem::Requirement
|
192
192
|
requirements:
|
193
193
|
- - ">="
|
@@ -201,7 +201,7 @@ dependencies:
|
|
201
201
|
- !ruby/object:Gem::Version
|
202
202
|
version: '0'
|
203
203
|
- !ruby/object:Gem::Dependency
|
204
|
-
name:
|
204
|
+
name: pg
|
205
205
|
requirement: !ruby/object:Gem::Requirement
|
206
206
|
requirements:
|
207
207
|
- - ">="
|
@@ -304,14 +304,14 @@ dependencies:
|
|
304
304
|
requirements:
|
305
305
|
- - "~>"
|
306
306
|
- !ruby/object:Gem::Version
|
307
|
-
version: '
|
307
|
+
version: '3.0'
|
308
308
|
type: :development
|
309
309
|
prerelease: false
|
310
310
|
version_requirements: !ruby/object:Gem::Requirement
|
311
311
|
requirements:
|
312
312
|
- - "~>"
|
313
313
|
- !ruby/object:Gem::Version
|
314
|
-
version: '
|
314
|
+
version: '3.0'
|
315
315
|
- !ruby/object:Gem::Dependency
|
316
316
|
name: sinatra
|
317
317
|
requirement: !ruby/object:Gem::Requirement
|
@@ -330,16 +330,16 @@ dependencies:
|
|
330
330
|
name: sinatra-contrib
|
331
331
|
requirement: !ruby/object:Gem::Requirement
|
332
332
|
requirements:
|
333
|
-
- - "
|
333
|
+
- - "~>"
|
334
334
|
- !ruby/object:Gem::Version
|
335
|
-
version: '
|
335
|
+
version: '3.1'
|
336
336
|
type: :development
|
337
337
|
prerelease: false
|
338
338
|
version_requirements: !ruby/object:Gem::Requirement
|
339
339
|
requirements:
|
340
|
-
- - "
|
340
|
+
- - "~>"
|
341
341
|
- !ruby/object:Gem::Version
|
342
|
-
version: '
|
342
|
+
version: '3.1'
|
343
343
|
- !ruby/object:Gem::Dependency
|
344
344
|
name: timecop
|
345
345
|
requirement: !ruby/object:Gem::Requirement
|
@@ -368,7 +368,7 @@ dependencies:
|
|
368
368
|
- - ">="
|
369
369
|
- !ruby/object:Gem::Version
|
370
370
|
version: '0'
|
371
|
-
description:
|
371
|
+
description:
|
372
372
|
email:
|
373
373
|
- cody@instructure.com
|
374
374
|
- evizitei@instructure.com
|
@@ -436,7 +436,6 @@ files:
|
|
436
436
|
- lib/delayed/periodic.rb
|
437
437
|
- lib/delayed/plugin.rb
|
438
438
|
- lib/delayed/pool.rb
|
439
|
-
- lib/delayed/rails_reloader_plugin.rb
|
440
439
|
- lib/delayed/server.rb
|
441
440
|
- lib/delayed/server/helpers.rb
|
442
441
|
- lib/delayed/server/public/css/app.css
|
@@ -462,7 +461,7 @@ homepage: https://github.com/instructure/inst-jobs
|
|
462
461
|
licenses: []
|
463
462
|
metadata:
|
464
463
|
rubygems_mfa_required: 'true'
|
465
|
-
post_install_message:
|
464
|
+
post_install_message:
|
466
465
|
rdoc_options: []
|
467
466
|
require_paths:
|
468
467
|
- lib
|
@@ -470,15 +469,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
470
469
|
requirements:
|
471
470
|
- - ">="
|
472
471
|
- !ruby/object:Gem::Version
|
473
|
-
version: '
|
472
|
+
version: '3.1'
|
474
473
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
475
474
|
requirements:
|
476
475
|
- - ">="
|
477
476
|
- !ruby/object:Gem::Version
|
478
477
|
version: '0'
|
479
478
|
requirements: []
|
480
|
-
rubygems_version: 3.
|
481
|
-
signing_key:
|
479
|
+
rubygems_version: 3.4.19
|
480
|
+
signing_key:
|
482
481
|
specification_version: 4
|
483
482
|
summary: Instructure-maintained fork of delayed_job
|
484
483
|
test_files: []
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "delayed/plugin"
|
4
|
-
|
5
|
-
module Delayed
|
6
|
-
class RailsReloaderPlugin < Plugin
|
7
|
-
callbacks do |lifecycle|
|
8
|
-
app = Rails.application
|
9
|
-
if app && !app.config.cache_classes
|
10
|
-
lifecycle.around(:perform) do |worker, job, &block|
|
11
|
-
reload = !app.config.reload_classes_only_on_change || app.reloaders.any?(&:updated?)
|
12
|
-
|
13
|
-
if reload
|
14
|
-
if defined?(ActiveSupport::Reloader)
|
15
|
-
Rails.application.reloader.reload!
|
16
|
-
else
|
17
|
-
ActionDispatch::Reloader.prepare!
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
begin
|
22
|
-
block.call(worker, job)
|
23
|
-
ensure
|
24
|
-
ActionDispatch::Reloader.cleanup! if reload && !defined?(ActiveSupport::Reloader)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|