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 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