inst-jobs 2.1.3 → 2.2.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.
- checksums.yaml +4 -4
- data/lib/delayed/periodic.rb +2 -8
- data/lib/delayed/pool.rb +31 -0
- data/lib/delayed/settings.rb +1 -0
- data/lib/delayed/version.rb +1 -1
- data/lib/delayed/worker/health_check.rb +5 -4
- data/spec/delayed/periodic_spec.rb +0 -10
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c062c222e731bd490efe572108a508bf78faabee4479f7fe6927a89688d9ef0b
|
4
|
+
data.tar.gz: 3b1678fc017230e990bc7e8d4e652c23ab59413953ce72a312b13adfa7626193
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8c1a722c17c9abc8f5c8a44cb28f6584dc9fb16c1edcccc8df566ad21a5f81af7a54fb70282e2689aee11947dcd96f44ca01dfe542d71c8d3d6b7f145a572ce7
|
7
|
+
data.tar.gz: 9a7a65c71820d4b04f1e1ac2bf498cf030490a597d075d87d4399a392a7da1bbf50cfb3d5eeb1dea9c357d11e00aabf5e469f062c1fe9cc4b02cc8ed08e1a192
|
data/lib/delayed/periodic.rb
CHANGED
@@ -53,18 +53,12 @@ class Periodic
|
|
53
53
|
end
|
54
54
|
|
55
55
|
def enqueue_args
|
56
|
-
# yes, checking for whether it is actually the boolean literal false,
|
57
|
-
# which means the consuming code really does not want this job to be
|
58
|
-
# a singleton at all.
|
59
|
-
non_singleton_periodic_job = @job_args[:singleton] == false
|
60
56
|
inferred_args = {
|
61
57
|
max_attempts: 1,
|
62
58
|
run_at: @cron.next_time(Delayed::Periodic.now).utc.to_time,
|
63
|
-
singleton:
|
59
|
+
singleton: tag,
|
60
|
+
on_conflict: :patient
|
64
61
|
}
|
65
|
-
unless non_singleton_periodic_job
|
66
|
-
inferred_args[:on_conflict] = :patient
|
67
|
-
end
|
68
62
|
@job_args.merge(inferred_args)
|
69
63
|
end
|
70
64
|
|
data/lib/delayed/pool.rb
CHANGED
@@ -39,6 +39,7 @@ class Pool
|
|
39
39
|
Process.wait unlock_pid
|
40
40
|
|
41
41
|
spawn_periodic_auditor
|
42
|
+
spawn_abandoned_job_cleanup
|
42
43
|
spawn_all_workers
|
43
44
|
say "Workers spawned"
|
44
45
|
join
|
@@ -111,6 +112,34 @@ class Pool
|
|
111
112
|
end
|
112
113
|
end
|
113
114
|
|
115
|
+
def spawn_abandoned_job_cleanup
|
116
|
+
return if Settings.disable_abandoned_job_cleanup
|
117
|
+
cleanup_interval_in_minutes = 60
|
118
|
+
@abandoned_cleanup_thread = Thread.new do
|
119
|
+
# every hour (staggered by process)
|
120
|
+
# check for dead jobs and cull them.
|
121
|
+
# Will actually be more often based on the
|
122
|
+
# number of worker nodes in the pool. This will actually
|
123
|
+
# be a max of N times per hour where N is the number of workers,
|
124
|
+
# but they won't overrun each other because the health check
|
125
|
+
# takes an advisory lock internally
|
126
|
+
sleep(rand(cleanup_interval_in_minutes * 60))
|
127
|
+
loop do
|
128
|
+
schedule_abandoned_job_cleanup
|
129
|
+
sleep(cleanup_interval_in_minutes * 60)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def schedule_abandoned_job_cleanup
|
135
|
+
pid = fork_with_reconnects do
|
136
|
+
# we want to avoid db connections in the main pool process
|
137
|
+
$0 = "delayed_abandoned_job_cleanup"
|
138
|
+
Delayed::Worker::HealthCheck.reschedule_abandoned_jobs
|
139
|
+
end
|
140
|
+
workers[pid] = :abandoned_job_cleanup
|
141
|
+
end
|
142
|
+
|
114
143
|
def spawn_periodic_auditor
|
115
144
|
return if Settings.disable_periodic_jobs
|
116
145
|
|
@@ -217,6 +246,8 @@ class Pool
|
|
217
246
|
case worker
|
218
247
|
when :periodic_audit
|
219
248
|
say "ran auditor: #{worker}"
|
249
|
+
when :abandoned_job_cleanup
|
250
|
+
say "ran cleanup: #{worker}"
|
220
251
|
when :work_queue
|
221
252
|
say "work queue exited, restarting", :info
|
222
253
|
spawn_work_queue
|
data/lib/delayed/settings.rb
CHANGED
data/lib/delayed/version.rb
CHANGED
@@ -23,12 +23,13 @@ module Delayed
|
|
23
23
|
def reschedule_abandoned_jobs
|
24
24
|
return if Settings.worker_health_check_type == :none
|
25
25
|
Delayed::Job.transaction do
|
26
|
-
# this
|
26
|
+
# this action is a special case, and SHOULD NOT be a periodic job
|
27
27
|
# because if it gets wiped out suddenly during execution
|
28
28
|
# it can't go clean up it's abandoned self. Therefore,
|
29
|
-
# we
|
30
|
-
#
|
31
|
-
#
|
29
|
+
# we expect it to get run from it's own process forked from the job pool
|
30
|
+
# and we try to get an advisory lock when it runs. If we succeed,
|
31
|
+
# no other worker is trying to do this right now (and if we abandon the
|
32
|
+
# operation, the transaction will end, releasing the advisory lock).
|
32
33
|
result = attempt_advisory_lock
|
33
34
|
return unless result
|
34
35
|
checker = Worker::HealthCheck.build(
|
@@ -27,15 +27,5 @@ RSpec.describe Delayed::Periodic do
|
|
27
27
|
expect(instance).to_not be_nil
|
28
28
|
expect(instance.enqueue_args[:singleton]).to eq("periodic: just a test")
|
29
29
|
end
|
30
|
-
|
31
|
-
it "uses no singleton if told to skip" do
|
32
|
-
Delayed::Periodic.cron job_name, '*/10 * * * *', {singleton: false} do
|
33
|
-
# no-op
|
34
|
-
end
|
35
|
-
instance = Delayed::Periodic.scheduled[job_name]
|
36
|
-
expect(instance).to_not be_nil
|
37
|
-
expect(instance.enqueue_args[:singleton]).to be_nil
|
38
|
-
Delayed::Periodic.perform_audit!
|
39
|
-
end
|
40
30
|
end
|
41
31
|
end
|
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: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tobias Luetke
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-01-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|