inst-jobs 0.14.7 → 0.14.8

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: 5a80182a2c2ba0fbaa7ccd9e88a092f171c724c9e9fa01db2081d8ec00e03474
4
- data.tar.gz: 1edd56027ef8cade2e9012945d3ec144d50b5315fc42867aed05179c4c9cbe05
3
+ metadata.gz: 200abc70c1bf8ecf6e041c76a5db366c6000895de24fa71c8af52924e206bd7a
4
+ data.tar.gz: 368611347a87da497e65fb2a190c1b4d1597ffb22bd985c7e2e9602c637516b5
5
5
  SHA512:
6
- metadata.gz: f9726d3b6c5f47a7510e97ba00661c690f1c3dbb06219289fc3fca8ce11898cc99fd348cf222ac2ceab4bbc4e1c79b3cd9dcba606a5b39cf38346fe1fd5fdab3
7
- data.tar.gz: 3056b193ca321a6c1db7e6e438538ceef74690fec95c7134cc9e21832eb4fea1cad884d2d9c69558fac562a7e725c9eb7acf1c3d2eec31d9ad87e387d09ebf5c
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)
@@ -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 }
@@ -1,3 +1,3 @@
1
1
  module Delayed
2
- VERSION = "0.14.7"
2
+ VERSION = "0.14.8"
3
3
  end
@@ -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
- if RUBY_PLATFORM =~ /darwin/
98
- mtime = `ps -o lstart -p #{Process.pid}`.sub(/\n$/, '')
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
- ActiveRecord::Migrator.migrate("db/migrate")
68
- ActiveRecord::Migrator.migrate("spec/migrate")
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.7
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-05-31 00:00:00.000000000 Z
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