inst-jobs 0.14.7 → 0.14.8
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 +5 -0
- data/lib/delayed/backend/base.rb +5 -0
- data/lib/delayed/version.rb +1 -1
- data/lib/delayed/worker/consul_health_check.rb +3 -31
- data/lib/delayed/worker/process_helper.rb +47 -0
- data/spec/active_record_job_spec.rb +7 -0
- data/spec/spec_helper.rb +11 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 200abc70c1bf8ecf6e041c76a5db366c6000895de24fa71c8af52924e206bd7a
|
4
|
+
data.tar.gz: 368611347a87da497e65fb2a190c1b4d1597ffb22bd985c7e2e9602c637516b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0beb49ab68860f4366b7d8e2863404a9d95d1fc03713cec9cd58ff192f8e4ecc7ea1207a58d8bac2ae672e616d227b0aa8b81c4ef83f3a02c8cd097e2ed68c94
|
7
|
+
data.tar.gz: 66779ae928d0e08b745d5cf50e559dff0ff7b4b833ebbf6be036ef6e5a8111622c8d887695ab646abce6e1afd953ddb9980d5434e10a2c2197fbb777f31e7b53
|
@@ -343,6 +343,11 @@ module Delayed
|
|
343
343
|
end
|
344
344
|
end
|
345
345
|
|
346
|
+
def self.processes_locked_locally(name: nil)
|
347
|
+
name ||= Socket.gethostname rescue x
|
348
|
+
where("locked_by LIKE ?", "#{name}:%").pluck(:locked_by).map{|locked_by| locked_by.split(":").last.to_i}
|
349
|
+
end
|
350
|
+
|
346
351
|
def self.unlock_orphaned_prefetched_jobs
|
347
352
|
horizon = db_time_now - Settings.parent_process[:prefetched_jobs_timeout] * 4
|
348
353
|
where("locked_by LIKE 'prefetch:%' AND locked_at<?", horizon).update_all(locked_at: nil, locked_by: nil)
|
data/lib/delayed/backend/base.rb
CHANGED
@@ -118,6 +118,11 @@ module Delayed
|
|
118
118
|
Time.now.utc
|
119
119
|
end
|
120
120
|
|
121
|
+
def processes_locked_locally(name: nil)
|
122
|
+
name ||= Socket.gethostname rescue x
|
123
|
+
running_jobs.select{|job| job.locked_by.start_with?("#{name}:")}.map{|job| job.locked_by.split(':').last.to_i}
|
124
|
+
end
|
125
|
+
|
121
126
|
def unlock_orphaned_prefetched_jobs
|
122
127
|
horizon = db_time_now - Settings.parent_process[:prefetched_jobs_timeout] * 4
|
123
128
|
orphaned_jobs = running_jobs.select { |job| job.locked_by.start_with?('prefetch:') && job.locked_at < horizon }
|
data/lib/delayed/version.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative 'health_check'
|
2
|
+
require_relative 'process_helper'
|
2
3
|
require 'socket'
|
3
4
|
|
4
5
|
module Delayed
|
@@ -10,31 +11,6 @@ module Delayed
|
|
10
11
|
DEFAULT_SERVICE_NAME = 'inst-jobs_worker'.freeze
|
11
12
|
attr_reader :agent_client, :catalog_client
|
12
13
|
|
13
|
-
STAT_LINUX = 'stat -f %%Y /proc/$WORKER_PID'
|
14
|
-
STAT_MAC = 'ps -o lstart -p $WORKER_PID'
|
15
|
-
STAT = RUBY_PLATFORM =~ /darwin/ ? STAT_MAC : STAT_LINUX
|
16
|
-
ALIVE_CHECK_LINUX = '[ -d "/proc/$WORKER_PID" ]'
|
17
|
-
ALIVE_CHECK_MAC = 'ps -p $WORKER_PID > /dev/null'
|
18
|
-
ALIVE_CHECK = RUBY_PLATFORM =~ /darwin/ ? ALIVE_CHECK_MAC : ALIVE_CHECK_LINUX
|
19
|
-
SCRIPT_TEMPLATE = <<-BASH.freeze
|
20
|
-
WORKER_PID="%<pid>d" # an example, filled from ruby when the check is created
|
21
|
-
ORIGINAL_MTIME="%<mtime>s" # an example, filled from ruby when the check is created
|
22
|
-
|
23
|
-
if #{ALIVE_CHECK}; then
|
24
|
-
CURRENT_MTIME=$(#{STAT})
|
25
|
-
|
26
|
-
if [ "$ORIGINAL_MTIME" = "$CURRENT_MTIME" ]; then
|
27
|
-
exit 0 # Happy day
|
28
|
-
else
|
29
|
-
echo "PID still exists but procfs entry has changed, current command:"
|
30
|
-
ps -p $WORKER_PID -o 'command='
|
31
|
-
exit 1 # Something is wrong, trigger a "warning" state
|
32
|
-
fi
|
33
|
-
else
|
34
|
-
exit 255 # The process is no more, trigger a "critical" state.
|
35
|
-
fi
|
36
|
-
BASH
|
37
|
-
|
38
14
|
def initialize(*args)
|
39
15
|
super
|
40
16
|
# Because we don't want the consul client to be a hard dependency we're
|
@@ -94,12 +70,8 @@ module Delayed
|
|
94
70
|
|
95
71
|
def check_script
|
96
72
|
return @check_script if @check_script
|
97
|
-
|
98
|
-
|
99
|
-
else
|
100
|
-
mtime = File::Stat.new("/proc/#{Process.pid}").mtime.to_i.to_s
|
101
|
-
end
|
102
|
-
@check_script = sprintf(SCRIPT_TEMPLATE, {pid: Process.pid, mtime: mtime})
|
73
|
+
mtime = ProcessHelper.mtime(Process.pid)
|
74
|
+
@check_script = ProcessHelper.check_script(Process.pid, mtime)
|
103
75
|
end
|
104
76
|
|
105
77
|
# This method is horrible, it takes advantage of the fact that docker uses
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Delayed
|
2
|
+
class Worker
|
3
|
+
module ProcessHelper
|
4
|
+
|
5
|
+
STAT_LINUX = 'stat --format=%%Y /proc/$WORKER_PID'
|
6
|
+
STAT_MAC = 'ps -o lstart -p $WORKER_PID'
|
7
|
+
STAT = RUBY_PLATFORM =~ /darwin/ ? STAT_MAC : STAT_LINUX
|
8
|
+
ALIVE_CHECK_LINUX = '[ -d "/proc/$WORKER_PID" ]'
|
9
|
+
ALIVE_CHECK_MAC = 'ps -p $WORKER_PID > /dev/null'
|
10
|
+
ALIVE_CHECK = RUBY_PLATFORM =~ /darwin/ ? ALIVE_CHECK_MAC : ALIVE_CHECK_LINUX
|
11
|
+
SCRIPT_TEMPLATE = <<-BASH.freeze
|
12
|
+
WORKER_PID="%<pid>d" # an example, filled from ruby when the check is created
|
13
|
+
ORIGINAL_MTIME="%<mtime>s" # an example, filled from ruby when the check is created
|
14
|
+
|
15
|
+
if #{ALIVE_CHECK}; then
|
16
|
+
CURRENT_MTIME=$(#{STAT})
|
17
|
+
|
18
|
+
if [ "$ORIGINAL_MTIME" = "$CURRENT_MTIME" ]; then
|
19
|
+
exit 0 # Happy day
|
20
|
+
else
|
21
|
+
echo "PID still exists but procfs entry has changed, current command:"
|
22
|
+
ps -p $WORKER_PID -o 'command='
|
23
|
+
exit 1 # Something is wrong, trigger a "warning" state
|
24
|
+
fi
|
25
|
+
else
|
26
|
+
exit 255 # The process is no more, trigger a "critical" state.
|
27
|
+
fi
|
28
|
+
BASH
|
29
|
+
|
30
|
+
def self.mtime(pid)
|
31
|
+
if RUBY_PLATFORM =~ /darwin/
|
32
|
+
`ps -o lstart -p #{pid}`.sub(/\n$/, '').presence
|
33
|
+
else
|
34
|
+
File::Stat.new("/proc/#{pid}").mtime.to_i.to_s rescue nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.check_script(pid, mtime)
|
39
|
+
sprintf(SCRIPT_TEMPLATE, {pid: pid, mtime: mtime})
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.process_is_still_running?(pid, mtime)
|
43
|
+
system(self.check_script(pid, mtime))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -261,6 +261,13 @@ describe 'Delayed::Backed::ActiveRecord::Job' do
|
|
261
261
|
expect(Delayed::Job.find(job2.id).locked_by).to eq 'prefetch:a'
|
262
262
|
end
|
263
263
|
|
264
|
+
it "gets process ids from locked_by" do
|
265
|
+
3.times.map { Delayed::Job.create :payload_object => SimpleJob.new }
|
266
|
+
locked_jobs = Delayed::Job.get_and_lock_next_available(['job42:2', 'job42:9001'])
|
267
|
+
expect(Delayed::Job.processes_locked_locally(name: 'job42').sort).to eq [2, 9001]
|
268
|
+
expect(Delayed::Job.processes_locked_locally(name: 'jobnotme')).to be_empty
|
269
|
+
end
|
270
|
+
|
264
271
|
it "allows fetching multiple jobs at once" do
|
265
272
|
jobs = 3.times.map { Delayed::Job.create :payload_object => SimpleJob.new }
|
266
273
|
locked_jobs = Delayed::Job.get_and_lock_next_available(['worker1', 'worker2'])
|
data/spec/spec_helper.rb
CHANGED
@@ -6,6 +6,7 @@ require 'rack/test'
|
|
6
6
|
require 'test_after_commit' if ::Rails.version < '5'
|
7
7
|
require 'timecop'
|
8
8
|
require 'pry'
|
9
|
+
require 'byebug'
|
9
10
|
|
10
11
|
RSpec.configure do |config|
|
11
12
|
|
@@ -55,6 +56,14 @@ if ::Rails.version < '5'
|
|
55
56
|
end
|
56
57
|
end
|
57
58
|
|
59
|
+
def migrate(file)
|
60
|
+
if ::Rails.version < '5.2'
|
61
|
+
ActiveRecord::Migrator.migrate(file)
|
62
|
+
else
|
63
|
+
ActiveRecord::MigrationContext.new(file).migrate
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
58
67
|
# create the test db if it does not exist, to help out wwtd
|
59
68
|
ActiveRecord::Base.establish_connection(connection_config.merge(database: 'postgres'))
|
60
69
|
begin
|
@@ -64,8 +73,8 @@ end
|
|
64
73
|
ActiveRecord::Base.establish_connection(connection_config)
|
65
74
|
# TODO reset db and migrate again, to test migrations
|
66
75
|
|
67
|
-
|
68
|
-
|
76
|
+
migrate("db/migrate")
|
77
|
+
migrate("spec/migrate")
|
69
78
|
Delayed::Backend::ActiveRecord::Job.reset_column_information
|
70
79
|
Delayed::Backend::ActiveRecord::Job::Failed.reset_column_information
|
71
80
|
|
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: 0.14.
|
4
|
+
version: 0.14.8
|
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: 2018-
|
12
|
+
date: 2018-06-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -390,6 +390,7 @@ files:
|
|
390
390
|
- lib/delayed/worker/consul_health_check.rb
|
391
391
|
- lib/delayed/worker/health_check.rb
|
392
392
|
- lib/delayed/worker/null_health_check.rb
|
393
|
+
- lib/delayed/worker/process_helper.rb
|
393
394
|
- lib/delayed/yaml_extensions.rb
|
394
395
|
- lib/delayed_job.rb
|
395
396
|
- lib/inst-jobs.rb
|