inst-jobs 0.14.0 → 0.14.1

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
  SHA1:
3
- metadata.gz: ee8d7326e878b8571d349ec95ae6b6b8870c8ca9
4
- data.tar.gz: 43c64c727119ba15d95a0a7f2e39c102068c1cce
3
+ metadata.gz: e485941f6b24b6f88e18b37c1b25e2cab3862630
4
+ data.tar.gz: 8f753f31b331870b59a226e65822619da4429ab1
5
5
  SHA512:
6
- metadata.gz: b9e12899372899fe7ae9ee0c2e692cbad12244f22f3507279ce7c4f9426f876bb058ef632c53c8c1b70d6c010bb9a7b63c441b6733b8fdfca77d2246ef358381
7
- data.tar.gz: 4e77f257047f61b065e0505994974d718a4f6a98b3ef956a640dc825f2eee3a6a07d24d10a0e0be017fce9aa034a630809b550460254d94a7eac2c7819306a51
6
+ metadata.gz: 0f33b3e301a818b103d98ed74bdff5baaee8387b7073a227945931dd6c60543bb072e009847bfc16aa6aba1c67813b1166e7af3877dfea8d0db5f722134b4e41
7
+ data.tar.gz: 686bdb0292db19d3662202020e7a21fc956dab17e4d68cfe671f6b1e80646baf329dcc5b6dd1b6b1c76120520fcb1d633b4495c1104e98d60da5e0bc1235d3be
@@ -312,12 +312,19 @@ module Delayed
312
312
  # on the strand but it's already running)
313
313
  def self.create_singleton(options)
314
314
  strand = options[:strand]
315
+ on_conflict = options.delete(:on_conflict) || :use_earliest
315
316
  transaction_for_singleton(strand) do
316
317
  job = self.where(:strand => strand, :locked_at => nil).order(:id).first
317
318
  new_job = new(options)
318
319
  if job
319
320
  new_job.initialize_defaults
320
- job.run_at = [job.run_at, new_job.run_at].min
321
+ job.run_at =
322
+ case on_conflict
323
+ when :use_earliest
324
+ [job.run_at, new_job.run_at].min
325
+ when :overwrite
326
+ new_job.run_at
327
+ end
321
328
  job.save! if job.changed?
322
329
  else
323
330
  new_job.save!
@@ -360,7 +360,7 @@ class Job
360
360
  end
361
361
 
362
362
  # not saved, just used as a marker when creating
363
- attr_accessor :singleton
363
+ attr_accessor :singleton, :on_conflict
364
364
 
365
365
  def transfer_lock!(from:, to:)
366
366
  lock_in_redis!(to)
@@ -442,7 +442,15 @@ class Job
442
442
  # replace this job with the other for returning.
443
443
  if job_id != self.id
444
444
  singleton = self.class.find(job_id)
445
- singleton.run_at = [singleton.run_at, run_at].min
445
+
446
+ self.on_conflict ||= :use_earliest
447
+ singleton.run_at =
448
+ case self.on_conflict
449
+ when :use_earliest
450
+ [singleton.run_at, run_at].min
451
+ when :overwrite
452
+ run_at
453
+ end
446
454
  singleton.save! if singleton.changed?
447
455
  COLUMNS.each { |c| send("#{c}=", singleton.send(c)) }
448
456
  end
@@ -20,8 +20,6 @@ class Periodic
20
20
  self.overrides.merge!(overrides)
21
21
  end
22
22
 
23
- STRAND = 'periodic scheduling'
24
-
25
23
  def self.cron(job_name, cron_line, job_args = {}, &block)
26
24
  raise ArgumentError, "job #{job_name} already scheduled!" if self.scheduled[job_name]
27
25
  cron_line = overrides[job_name] || cron_line
@@ -19,6 +19,8 @@ module Delayed
19
19
  :sleep_delay,
20
20
  :sleep_delay_stagger,
21
21
  :slow_exit_timeout,
22
+ :worker_health_check_type,
23
+ :worker_health_check_config,
22
24
  :worker_procname_prefix,
23
25
  ]
24
26
  SETTINGS_WITH_ARGS = [ :num_strands ]
@@ -69,6 +71,9 @@ module Delayed
69
71
  self.kill_workers_on_exit = true
70
72
  self.slow_exit_timeout = 20
71
73
 
74
+ self.worker_health_check_type = :none
75
+ self.worker_health_check_config = {}
76
+
72
77
  def self.worker_config(config_filename = nil)
73
78
  config_filename ||= default_worker_config_name
74
79
  config = YAML.load(ERB.new(File.read(config_filename)).result)
@@ -117,5 +122,9 @@ module Delayed
117
122
  raise 'Parent process configurations must be a hash!' unless Hash === new_config
118
123
  @@parent_process = PARENT_PROCESS_DEFAULTS.merge(new_config)
119
124
  end
125
+
126
+ def self.worker_health_check_config=(new_config)
127
+ @@worker_health_check_config = (new_config || {}).with_indifferent_access
128
+ end
120
129
  end
121
130
  end
@@ -1,3 +1,3 @@
1
1
  module Delayed
2
- VERSION = "0.14.0"
2
+ VERSION = "0.14.1"
3
3
  end
@@ -0,0 +1,108 @@
1
+ require_relative 'health_check'
2
+ require 'socket'
3
+
4
+ module Delayed
5
+ class Worker
6
+ class ConsulHealthCheck < HealthCheck
7
+ self.type_name = :consul
8
+
9
+ CONSUL_CONFIG_KEYS = %w{url host port ssl token connect_timeout receive_timeout send_timeout}.map(&:freeze).freeze
10
+ DEFAULT_SERVICE_NAME = 'inst-jobs_worker'.freeze
11
+ attr_reader :agent_client, :catalog_client
12
+
13
+ SCRIPT_TEMPLATE = <<-BASH.freeze
14
+ WORKER_PID="%<pid>d" # an example, filled from ruby when the check is created
15
+ ORIGINAL_MTIME="%<mtime>d" # an example, filled from ruby when the check is created
16
+
17
+ if [ -d "/proc/$WORKER_PID" ]; then
18
+ CURRENT_MTIME=$(stat -f %%Y /proc/$WORKER_PID)
19
+
20
+ if [ "$ORIGINAL_MTIME" = "$CURRENT_MTIME" ]; then
21
+ exit 0 # Happy day
22
+ else
23
+ echo "PID still exists but procfs entry has changed, current command:"
24
+ ps -p $PID -o 'command='
25
+ exit 1 # Something is wrong, trigger a "warning" state
26
+ fi
27
+ else
28
+ exit 255 # The process is no more, trigger a "critical" state.
29
+ fi
30
+ BASH
31
+
32
+ def initialize(*args)
33
+ super
34
+ # Because we don't want the consul client to be a hard dependency we're
35
+ # only requiring it once it's absolutely needed
36
+ require 'imperium'
37
+
38
+ if config.keys.any? { |k| CONSUL_CONFIG_KEYS.include?(k) }
39
+ consul_config = Imperium::Configuration.new.tap do |conf|
40
+ CONSUL_CONFIG_KEYS.each do |key|
41
+ conf.send("#{key}=", config[key]) if config[key]
42
+ end
43
+ end
44
+ @agent_client = Imperium::Agent.new(consul_config)
45
+ @catalog_client = Imperium::Catalog.new(consul_config)
46
+ else
47
+ @agent_client = Imperium::Agent.default_client
48
+ @catalog_client = Imperium::Catalog.default_client
49
+ end
50
+ end
51
+
52
+ def start
53
+ service = Imperium::Service.new({
54
+ id: worker_name,
55
+ name: service_name,
56
+ })
57
+ service.add_check(check_attributes)
58
+ response = @agent_client.register_service(service)
59
+ response.ok?
60
+ end
61
+
62
+ def stop
63
+ response = @agent_client.deregister_service(worker_name)
64
+ response.ok? || response.not_found?
65
+ end
66
+
67
+ def live_workers
68
+ live_nodes = @catalog_client.list_nodes_for_service(service_name)
69
+ if live_nodes.ok?
70
+ live_nodes.map(&:service_id)
71
+ else
72
+ raise "Unable to read from Consul catalog: #{live_nodes.content}"
73
+ end
74
+ end
75
+
76
+ private
77
+
78
+ def check_attributes
79
+ {
80
+ script: check_script,
81
+ status: 'passing',
82
+ interval: @config.fetch(:check_interval, '5m'),
83
+ deregister_critical_service_after: @config.fetch(:deregister_service_delay, '10m'),
84
+ }.tap do |h|
85
+ h[:docker_container_id] = docker_container_id if @config['docker']
86
+ end
87
+ end
88
+
89
+ def check_script
90
+ return @check_script if @check_script
91
+ stat = File::Stat.new("/proc/#{Process.pid}")
92
+ @check_script = sprintf(SCRIPT_TEMPLATE, {pid: Process.pid, mtime: stat.mtime.to_i})
93
+ end
94
+
95
+ # This method is horrible, it takes advantage of the fact that docker uses
96
+ # cgroups for part of its magic and also uses the container id as the cgroup name
97
+ def docker_container_id
98
+ return @docker_container_id if @docker_container_id
99
+ content = File.read("/proc/1/cgroup").split("\n")
100
+ @docker_container_id = content.last.split("/").last
101
+ end
102
+
103
+ def service_name
104
+ @service_name ||= @config.fetch('service_name', DEFAULT_SERVICE_NAME)
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,57 @@
1
+ module Delayed
2
+ class Worker
3
+ class HealthCheck
4
+ @subclasses = []
5
+
6
+ class << self
7
+ attr_accessor :type_name
8
+ attr_reader :subclasses
9
+
10
+ def inherited(subclass)
11
+ @subclasses << subclass
12
+ end
13
+
14
+ def build(type:, worker_name:, config: {})
15
+ type = type.to_sym
16
+ klass = @subclasses.find { |sc| sc.type_name == type }
17
+ raise ArgumentError, "Unable to build a HealthCheck for type #{type}" unless klass
18
+ klass.new(worker_name: worker_name, config: config)
19
+ end
20
+
21
+ def reschedule_abandoned_jobs
22
+ checker = Worker::HealthCheck.build(
23
+ type: Settings.worker_health_check_type,
24
+ config: Settings.worker_health_check_config,
25
+ worker_name: 'cleanup-crew'
26
+ )
27
+ live_workers = checker.live_workers
28
+
29
+ Delayed::Job.running_jobs.each do |job|
30
+ unless live_workers.include?(job.locked_by)
31
+ job.reschedule
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ attr_accessor :config, :worker_name
38
+
39
+ def initialize(worker_name:, config: {})
40
+ @config = config.with_indifferent_access
41
+ @worker_name = worker_name
42
+ end
43
+
44
+ def start
45
+ raise NotImplementedError
46
+ end
47
+
48
+ def stop
49
+ raise NotImplementedError
50
+ end
51
+
52
+ def live_workers
53
+ raise NotImplementedError
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,11 @@
1
+ module Delayed
2
+ class Worker
3
+ class NullHealthCheck < HealthCheck
4
+ self.type_name = :none
5
+
6
+ attr_reader *%i{start stop}
7
+
8
+ def live_workers; []; end
9
+ end
10
+ end
11
+ end
@@ -51,6 +51,8 @@ class Worker
51
51
  @max_job_count = options[:worker_max_job_count].to_i
52
52
  @max_memory_usage = options[:worker_max_memory_usage].to_i
53
53
  @work_queue = options.delete(:work_queue) || WorkQueue::InProcess.new
54
+ @health_check_type = Settings.worker_health_check_type
55
+ @health_check_config = Settings.worker_health_check_config
54
56
  @config = options
55
57
  @job_count = 0
56
58
 
@@ -99,6 +101,8 @@ class Worker
99
101
  trap(sig) { @signal_queue << sig; wake_up }
100
102
  end
101
103
 
104
+ health_check.start
105
+
102
106
  signal_processor = Thread.new do
103
107
  loop do
104
108
  @self_pipe[0].read(1)
@@ -121,14 +125,17 @@ class Worker
121
125
  end
122
126
  end
123
127
 
124
- work_queue.close
125
- signal_processor.kill
126
- signal_processor.join
127
128
  logger.info "Stopping worker"
128
129
  rescue => e
129
130
  Rails.logger.fatal("Child process died: #{e.inspect}") rescue nil
130
131
  self.class.lifecycle.run_callbacks(:exceptional_exit, self, e) { }
131
132
  ensure
133
+ health_check.stop
134
+ work_queue.close
135
+ if signal_processor
136
+ signal_processor.kill
137
+ signal_processor.join
138
+ end
132
139
  Delayed::Job.clear_locks!(name)
133
140
  end
134
141
 
@@ -248,6 +255,14 @@ class Worker
248
255
  ENV['TMPDIR'] = previous_tmpdir
249
256
  end
250
257
 
258
+ def health_check
259
+ @health_check ||= HealthCheck.build(
260
+ type: @health_check_type,
261
+ worker_name: name,
262
+ config: @health_check_config
263
+ )
264
+ end
265
+
251
266
  # `sample` reports KB, not B
252
267
  if File.directory?("/proc")
253
268
  # linux w/ proc fs
data/lib/delayed_job.rb CHANGED
@@ -36,6 +36,11 @@ require 'delayed/periodic'
36
36
  require 'delayed/plugin'
37
37
  require 'delayed/pool'
38
38
  require 'delayed/worker'
39
+
40
+ require 'delayed/worker/health_check'
41
+ require 'delayed/worker/consul_health_check'
42
+ require 'delayed/worker/null_health_check'
43
+
39
44
  require 'delayed/work_queue/in_process'
40
45
  require 'delayed/work_queue/parent_process'
41
46
 
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+ require 'imperium'
3
+
4
+ RSpec.describe Delayed::Worker::ConsulHealthCheck do
5
+ let(:health_check) { Delayed::Worker::ConsulHealthCheck.new(worker_name: 'foobar') }
6
+
7
+ # can't use a verifying double for the response because the methods we're
8
+ # tryig to stub are actually on HTTP::Message
9
+ let(:response) { double('Imperium::Response') }
10
+ let(:agent_client) { instance_double(Imperium::Agent) }
11
+
12
+ before do
13
+ allow(Imperium::Agent).to receive(:default_client).and_return(agent_client)
14
+ end
15
+
16
+ describe '#initialize' do
17
+ it 'must use the default agent client when the config is mostly empty' do
18
+ check = Delayed::Worker::ConsulHealthCheck.new({worker_name: 'foobar'})
19
+ expect(check.agent_client).to eq Imperium::Agent.default_client
20
+ end
21
+
22
+ it 'must create a new agent API client when the config has relevant keys set' do
23
+ check = Delayed::Worker::ConsulHealthCheck.new(worker_name: 'foobar', config: {url: 'http://consul.example.com:8500'})
24
+ agent_client = check.agent_client
25
+ expect(agent_client).to_not eq Imperium::Agent.default_client
26
+ expect(agent_client.config.url.to_s).to eq 'http://consul.example.com:8500'
27
+ end
28
+ end
29
+
30
+ describe '#start' do
31
+ it 'must register this process as a service with consul' do
32
+ expect(response).to receive(:ok?).and_return(true)
33
+ expect(agent_client).to receive(:register_service)
34
+ .with(an_instance_of(Imperium::Service))
35
+ .and_return(response)
36
+ health_check.start
37
+ end
38
+
39
+
40
+ it 'must supply a script style check' do
41
+ allow(response).to receive(:ok?).and_return(true)
42
+ allow(agent_client).to receive(:register_service) { |service|
43
+ check = service.checks.first
44
+ expect(check.script).to_not be_nil
45
+ response
46
+ }
47
+ health_check.start
48
+ end
49
+
50
+ it 'must include the docker container id when the docker option is set to true' do
51
+ local_health_check = Delayed::Worker::ConsulHealthCheck.new(
52
+ worker_name: 'foobar',
53
+ config: {docker: true}
54
+ )
55
+ allow(response).to receive(:ok?).and_return(true)
56
+ allow(agent_client).to receive(:register_service) { |service|
57
+ check = service.checks.first
58
+ expect(check.docker_container_id).to_not be_nil
59
+ response
60
+ }
61
+ local_health_check.start
62
+ end
63
+ end
64
+
65
+ describe '#stop' do
66
+ it 'must deregister the service from consul' do
67
+ allow(response).to receive(:ok?).and_return(true)
68
+ expect(agent_client).to receive(:deregister_service)
69
+ .with(health_check.worker_name)
70
+ .and_return(response)
71
+ health_check.stop
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,98 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Delayed::Worker::HealthCheck do
4
+ let(:klass) { Class.new(Delayed::Worker::HealthCheck) { self.type_name = :test } }
5
+
6
+ before do
7
+ klass # Gotta make sure the class has been defined before we try to use it
8
+ end
9
+
10
+ after do
11
+ Delayed::Worker::HealthCheck.subclasses.delete(klass)
12
+ end
13
+
14
+ it "must maintain a list of its subclasses" do
15
+ klass
16
+ expect(Delayed::Worker::HealthCheck.subclasses).to include klass
17
+ end
18
+
19
+ describe '.build(type:, config: {})' do
20
+ it 'must select the concrete class to use by the type_name in the subclass' do
21
+ check = Delayed::Worker::HealthCheck.build(type: 'test', worker_name: 'foobar')
22
+ expect(check).to be_a(klass)
23
+ end
24
+
25
+ it "must raise ArgumentError when the specified type doesn't exist" do
26
+ expect {
27
+ Delayed::Worker::HealthCheck.build(type: 'nope', config: {worker_name: 'foobar'})
28
+ }.to raise_error ArgumentError
29
+ end
30
+
31
+ it 'must initiaize the specified class using the supplied config' do
32
+ config = {foo: 'bar'}.with_indifferent_access
33
+ check = Delayed::Worker::HealthCheck.build(type: 'test', worker_name: 'foobar', config: config)
34
+ expect(check.config).to eq config
35
+ end
36
+ end
37
+
38
+ describe '.reschedule_abandoned_jobs' do
39
+ let(:klass) { Class.new(Delayed::Worker::HealthCheck) {
40
+ self.type_name = :fake
41
+ class << self
42
+ attr_accessor :live_workers
43
+ end
44
+
45
+ def live_workers
46
+ self.class.live_workers
47
+ end
48
+ } }
49
+
50
+ let(:initial_run_at) { Time.zone.now }
51
+
52
+ before do
53
+ klass.live_workers = %w{alive}
54
+ Delayed.select_backend(Delayed::Backend::ActiveRecord::Job)
55
+
56
+ 2.times { Delayed::Job.enqueue(SimpleJob.new, run_at: initial_run_at, max_attempts: 4) }
57
+ @alive_job = Delayed::Job.first
58
+ @alive_job.update_attributes!({
59
+ locked_by: 'alive',
60
+ locked_at: initial_run_at
61
+ })
62
+ @dead_job = Delayed::Job.last
63
+ @dead_job.update_attributes!({
64
+ locked_by: 'dead',
65
+ locked_at: initial_run_at
66
+ })
67
+ Delayed::Settings.worker_health_check_type = :fake
68
+ Delayed::Settings.worker_health_check_config = {}
69
+ Delayed::Worker::HealthCheck.reschedule_abandoned_jobs
70
+ end
71
+
72
+ after do
73
+ Delayed::Worker::HealthCheck.subclasses.delete(klass)
74
+ Delayed::Settings.worker_health_check_type = :none
75
+ Delayed::Settings.worker_health_check_config = {}
76
+ end
77
+
78
+ it 'must leave jobs locked by live workers alone' do
79
+ @alive_job.reload
80
+ expect(@alive_job.run_at.to_i).to eq initial_run_at.to_i
81
+ expect(@alive_job.locked_at.to_i).to eq initial_run_at.to_i
82
+ expect(@alive_job.locked_by).to eq 'alive'
83
+ end
84
+
85
+ it 'must reschedule jobs locked by dead workers' do
86
+ @dead_job.reload
87
+ expect(@dead_job.run_at).to be > initial_run_at
88
+ expect(@dead_job.locked_at).to be_nil
89
+ expect(@dead_job.locked_by).to be_nil
90
+ end
91
+ end
92
+
93
+ describe '#initialize' do
94
+ it 'must raise ArgumentError when the worker name is not supplied' do
95
+ expect { klass.new }.to raise_error ArgumentError
96
+ end
97
+ end
98
+ end
@@ -356,6 +356,19 @@ shared_examples_for 'a backend' do
356
356
  # it should be scheduled to run immediately
357
357
  Delayed::Job.get_and_lock_next_available('w1').should == job1
358
358
  end
359
+
360
+ it "should update existing job to a later date if requested" do
361
+ t1 = 1.hour.from_now
362
+ t2 = 2.hours.from_now
363
+ job1 = create_job(singleton: 'myjobs', run_at: t1)
364
+ job2 = create_job(singleton: 'myjobs', run_at: t2)
365
+ job2.should == job1
366
+ job2.run_at.to_i.should == t1.to_i
367
+
368
+ job3 = create_job(singleton: 'myjobs', run_at: t2, on_conflict: :overwrite)
369
+ job3.should == job1
370
+ job3.run_at.to_i.should == t2.to_i
371
+ end
359
372
  end
360
373
  end
361
374
 
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.0
4
+ version: 0.14.1
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: 2017-09-19 00:00:00.000000000 Z
12
+ date: 2017-11-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: after_transaction_commit
@@ -255,6 +255,20 @@ dependencies:
255
255
  - - ">="
256
256
  - !ruby/object:Gem::Version
257
257
  version: '0'
258
+ - !ruby/object:Gem::Dependency
259
+ name: imperium
260
+ requirement: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - ">="
263
+ - !ruby/object:Gem::Version
264
+ version: 0.2.3
265
+ type: :development
266
+ prerelease: false
267
+ version_requirements: !ruby/object:Gem::Requirement
268
+ requirements:
269
+ - - ">="
270
+ - !ruby/object:Gem::Version
271
+ version: 0.2.3
258
272
  description:
259
273
  email:
260
274
  - brianp@instructure.com
@@ -325,6 +339,9 @@ files:
325
339
  - lib/delayed/work_queue/parent_process/client.rb
326
340
  - lib/delayed/work_queue/parent_process/server.rb
327
341
  - lib/delayed/worker.rb
342
+ - lib/delayed/worker/consul_health_check.rb
343
+ - lib/delayed/worker/health_check.rb
344
+ - lib/delayed/worker/null_health_check.rb
328
345
  - lib/delayed/yaml_extensions.rb
329
346
  - lib/delayed_job.rb
330
347
  - lib/inst-jobs.rb
@@ -337,13 +354,12 @@ files:
337
354
  - spec/delayed/work_queue/parent_process/client_spec.rb
338
355
  - spec/delayed/work_queue/parent_process/server_spec.rb
339
356
  - spec/delayed/work_queue/parent_process_spec.rb
357
+ - spec/delayed/worker/consul_health_check_spec.rb
358
+ - spec/delayed/worker/health_check_spec.rb
340
359
  - spec/delayed/worker_spec.rb
341
360
  - spec/gemfiles/42.gemfile
342
- - spec/gemfiles/42.gemfile.lock
343
361
  - spec/gemfiles/50.gemfile
344
- - spec/gemfiles/50.gemfile.lock
345
362
  - spec/gemfiles/51.gemfile
346
- - spec/gemfiles/51.gemfile.lock
347
363
  - spec/migrate/20140924140513_add_story_table.rb
348
364
  - spec/redis_job_spec.rb
349
365
  - spec/sample_jobs.rb
@@ -374,7 +390,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
374
390
  version: '0'
375
391
  requirements: []
376
392
  rubyforge_project:
377
- rubygems_version: 2.6.13
393
+ rubygems_version: 2.6.10
378
394
  signing_key:
379
395
  specification_version: 4
380
396
  summary: Instructure-maintained fork of delayed_job
@@ -388,13 +404,12 @@ test_files:
388
404
  - spec/delayed/work_queue/parent_process/client_spec.rb
389
405
  - spec/delayed/work_queue/parent_process/server_spec.rb
390
406
  - spec/delayed/work_queue/parent_process_spec.rb
407
+ - spec/delayed/worker/consul_health_check_spec.rb
408
+ - spec/delayed/worker/health_check_spec.rb
391
409
  - spec/delayed/worker_spec.rb
392
410
  - spec/gemfiles/42.gemfile
393
- - spec/gemfiles/42.gemfile.lock
394
411
  - spec/gemfiles/50.gemfile
395
- - spec/gemfiles/50.gemfile.lock
396
412
  - spec/gemfiles/51.gemfile
397
- - spec/gemfiles/51.gemfile.lock
398
413
  - spec/migrate/20140924140513_add_story_table.rb
399
414
  - spec/redis_job_spec.rb
400
415
  - spec/sample_jobs.rb
@@ -1,182 +0,0 @@
1
- PATH
2
- remote: ../..
3
- specs:
4
- inst-jobs (0.13.4)
5
- after_transaction_commit (>= 1.0, < 3)
6
- rails (>= 4.2)
7
- redis (> 3.0)
8
- redis-scripting (~> 1.0.1)
9
- rufus-scheduler (~> 3.4)
10
-
11
- GEM
12
- remote: https://rubygems.org/
13
- specs:
14
- actionmailer (4.2.9)
15
- actionpack (= 4.2.9)
16
- actionview (= 4.2.9)
17
- activejob (= 4.2.9)
18
- mail (~> 2.5, >= 2.5.4)
19
- rails-dom-testing (~> 1.0, >= 1.0.5)
20
- actionpack (4.2.9)
21
- actionview (= 4.2.9)
22
- activesupport (= 4.2.9)
23
- rack (~> 1.6)
24
- rack-test (~> 0.6.2)
25
- rails-dom-testing (~> 1.0, >= 1.0.5)
26
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
27
- actionview (4.2.9)
28
- activesupport (= 4.2.9)
29
- builder (~> 3.1)
30
- erubis (~> 2.7.0)
31
- rails-dom-testing (~> 1.0, >= 1.0.5)
32
- rails-html-sanitizer (~> 1.0, >= 1.0.3)
33
- activejob (4.2.9)
34
- activesupport (= 4.2.9)
35
- globalid (>= 0.3.0)
36
- activemodel (4.2.9)
37
- activesupport (= 4.2.9)
38
- builder (~> 3.1)
39
- activerecord (4.2.9)
40
- activemodel (= 4.2.9)
41
- activesupport (= 4.2.9)
42
- arel (~> 6.0)
43
- activesupport (4.2.9)
44
- i18n (~> 0.7)
45
- minitest (~> 5.1)
46
- thread_safe (~> 0.3, >= 0.3.4)
47
- tzinfo (~> 1.1)
48
- after_transaction_commit (1.1.2)
49
- activerecord (>= 4.0)
50
- arel (6.0.4)
51
- backports (3.8.0)
52
- builder (3.2.3)
53
- bump (0.5.4)
54
- byebug (9.0.6)
55
- coderay (1.1.1)
56
- concurrent-ruby (1.0.5)
57
- database_cleaner (1.6.1)
58
- diff-lcs (1.3)
59
- erubis (2.7.0)
60
- et-orbi (1.0.5)
61
- tzinfo
62
- globalid (0.4.0)
63
- activesupport (>= 4.2.0)
64
- i18n (0.8.6)
65
- loofah (2.0.3)
66
- nokogiri (>= 1.5.9)
67
- mail (2.6.6)
68
- mime-types (>= 1.16, < 4)
69
- method_source (0.8.2)
70
- mime-types (3.1)
71
- mime-types-data (~> 3.2015)
72
- mime-types-data (3.2016.0521)
73
- mini_portile2 (2.2.0)
74
- minitest (5.10.3)
75
- multi_json (1.12.1)
76
- nokogiri (1.8.0)
77
- mini_portile2 (~> 2.2.0)
78
- pg (0.21.0)
79
- pry (0.10.4)
80
- coderay (~> 1.1.0)
81
- method_source (~> 0.8.1)
82
- slop (~> 3.4)
83
- rack (1.6.8)
84
- rack-protection (1.5.3)
85
- rack
86
- rack-test (0.6.3)
87
- rack (>= 1.0)
88
- rails (4.2.9)
89
- actionmailer (= 4.2.9)
90
- actionpack (= 4.2.9)
91
- actionview (= 4.2.9)
92
- activejob (= 4.2.9)
93
- activemodel (= 4.2.9)
94
- activerecord (= 4.2.9)
95
- activesupport (= 4.2.9)
96
- bundler (>= 1.3.0, < 2.0)
97
- railties (= 4.2.9)
98
- sprockets-rails
99
- rails-deprecated_sanitizer (1.0.3)
100
- activesupport (>= 4.2.0.alpha)
101
- rails-dom-testing (1.0.8)
102
- activesupport (>= 4.2.0.beta, < 5.0)
103
- nokogiri (~> 1.6)
104
- rails-deprecated_sanitizer (>= 1.0.1)
105
- rails-html-sanitizer (1.0.3)
106
- loofah (~> 2.0)
107
- railties (4.2.9)
108
- actionpack (= 4.2.9)
109
- activesupport (= 4.2.9)
110
- rake (>= 0.8.7)
111
- thor (>= 0.18.1, < 2.0)
112
- rake (12.0.0)
113
- redis (3.3.3)
114
- redis-scripting (1.0.1)
115
- redis (>= 3.0)
116
- rspec (3.4.0)
117
- rspec-core (~> 3.4.0)
118
- rspec-expectations (~> 3.4.0)
119
- rspec-mocks (~> 3.4.0)
120
- rspec-core (3.4.4)
121
- rspec-support (~> 3.4.0)
122
- rspec-expectations (3.4.0)
123
- diff-lcs (>= 1.2.0, < 2.0)
124
- rspec-support (~> 3.4.0)
125
- rspec-mocks (3.4.1)
126
- diff-lcs (>= 1.2.0, < 2.0)
127
- rspec-support (~> 3.4.0)
128
- rspec-support (3.4.1)
129
- rufus-scheduler (3.4.2)
130
- et-orbi (~> 1.0)
131
- sinatra (1.4.8)
132
- rack (~> 1.5)
133
- rack-protection (~> 1.4)
134
- tilt (>= 1.3, < 3)
135
- sinatra-contrib (1.4.7)
136
- backports (>= 2.0)
137
- multi_json
138
- rack-protection
139
- rack-test
140
- sinatra (~> 1.4.0)
141
- tilt (>= 1.3, < 3)
142
- slop (3.6.0)
143
- sprockets (3.7.1)
144
- concurrent-ruby (~> 1.0)
145
- rack (> 1, < 3)
146
- sprockets-rails (3.2.0)
147
- actionpack (>= 4.0)
148
- activesupport (>= 4.0)
149
- sprockets (>= 3.0.0)
150
- test_after_commit (0.4.1)
151
- activerecord (>= 3.2)
152
- thor (0.19.4)
153
- thread_safe (0.3.6)
154
- tilt (2.0.8)
155
- timecop (0.7.1)
156
- tzinfo (1.2.3)
157
- thread_safe (~> 0.1)
158
- wwtd (1.3.0)
159
-
160
- PLATFORMS
161
- ruby
162
-
163
- DEPENDENCIES
164
- after_transaction_commit (< 2)
165
- bump
166
- byebug
167
- database_cleaner (= 1.6.1)
168
- inst-jobs!
169
- pg
170
- pry
171
- rack-test
172
- rails (~> 4.2.5)
173
- rake
174
- rspec (= 3.4.0)
175
- sinatra
176
- sinatra-contrib
177
- test_after_commit (= 0.4.1)
178
- timecop (= 0.7.1)
179
- wwtd (~> 1.3.0)
180
-
181
- BUNDLED WITH
182
- 1.15.3
@@ -1,187 +0,0 @@
1
- PATH
2
- remote: ../..
3
- specs:
4
- inst-jobs (0.13.4)
5
- after_transaction_commit (>= 1.0, < 3)
6
- rails (>= 4.2)
7
- redis (> 3.0)
8
- redis-scripting (~> 1.0.1)
9
- rufus-scheduler (~> 3.4)
10
-
11
- GEM
12
- remote: https://rubygems.org/
13
- specs:
14
- actioncable (5.0.5)
15
- actionpack (= 5.0.5)
16
- nio4r (>= 1.2, < 3.0)
17
- websocket-driver (~> 0.6.1)
18
- actionmailer (5.0.5)
19
- actionpack (= 5.0.5)
20
- actionview (= 5.0.5)
21
- activejob (= 5.0.5)
22
- mail (~> 2.5, >= 2.5.4)
23
- rails-dom-testing (~> 2.0)
24
- actionpack (5.0.5)
25
- actionview (= 5.0.5)
26
- activesupport (= 5.0.5)
27
- rack (~> 2.0)
28
- rack-test (~> 0.6.3)
29
- rails-dom-testing (~> 2.0)
30
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
31
- actionview (5.0.5)
32
- activesupport (= 5.0.5)
33
- builder (~> 3.1)
34
- erubis (~> 2.7.0)
35
- rails-dom-testing (~> 2.0)
36
- rails-html-sanitizer (~> 1.0, >= 1.0.3)
37
- activejob (5.0.5)
38
- activesupport (= 5.0.5)
39
- globalid (>= 0.3.6)
40
- activemodel (5.0.5)
41
- activesupport (= 5.0.5)
42
- activerecord (5.0.5)
43
- activemodel (= 5.0.5)
44
- activesupport (= 5.0.5)
45
- arel (~> 7.0)
46
- activesupport (5.0.5)
47
- concurrent-ruby (~> 1.0, >= 1.0.2)
48
- i18n (~> 0.7)
49
- minitest (~> 5.1)
50
- tzinfo (~> 1.1)
51
- after_transaction_commit (2.0.0)
52
- activerecord (>= 5.0)
53
- arel (7.1.4)
54
- backports (3.8.0)
55
- builder (3.2.3)
56
- bump (0.5.4)
57
- byebug (9.0.6)
58
- coderay (1.1.1)
59
- concurrent-ruby (1.0.5)
60
- database_cleaner (1.6.1)
61
- diff-lcs (1.3)
62
- erubis (2.7.0)
63
- et-orbi (1.0.5)
64
- tzinfo
65
- globalid (0.4.0)
66
- activesupport (>= 4.2.0)
67
- i18n (0.8.6)
68
- loofah (2.0.3)
69
- nokogiri (>= 1.5.9)
70
- mail (2.6.6)
71
- mime-types (>= 1.16, < 4)
72
- method_source (0.8.2)
73
- mime-types (3.1)
74
- mime-types-data (~> 3.2015)
75
- mime-types-data (3.2016.0521)
76
- mini_portile2 (2.2.0)
77
- minitest (5.10.3)
78
- multi_json (1.12.1)
79
- mustermann (1.0.0.beta2)
80
- nio4r (2.1.0)
81
- nokogiri (1.8.0)
82
- mini_portile2 (~> 2.2.0)
83
- pg (0.21.0)
84
- pry (0.10.4)
85
- coderay (~> 1.1.0)
86
- method_source (~> 0.8.1)
87
- slop (~> 3.4)
88
- rack (2.0.3)
89
- rack-protection (2.0.0.beta2)
90
- rack
91
- rack-test (0.6.3)
92
- rack (>= 1.0)
93
- rails (5.0.5)
94
- actioncable (= 5.0.5)
95
- actionmailer (= 5.0.5)
96
- actionpack (= 5.0.5)
97
- actionview (= 5.0.5)
98
- activejob (= 5.0.5)
99
- activemodel (= 5.0.5)
100
- activerecord (= 5.0.5)
101
- activesupport (= 5.0.5)
102
- bundler (>= 1.3.0)
103
- railties (= 5.0.5)
104
- sprockets-rails (>= 2.0.0)
105
- rails-dom-testing (2.0.3)
106
- activesupport (>= 4.2.0)
107
- nokogiri (>= 1.6)
108
- rails-html-sanitizer (1.0.3)
109
- loofah (~> 2.0)
110
- railties (5.0.5)
111
- actionpack (= 5.0.5)
112
- activesupport (= 5.0.5)
113
- method_source
114
- rake (>= 0.8.7)
115
- thor (>= 0.18.1, < 2.0)
116
- rake (12.0.0)
117
- redis (3.3.3)
118
- redis-scripting (1.0.1)
119
- redis (>= 3.0)
120
- rspec (3.4.0)
121
- rspec-core (~> 3.4.0)
122
- rspec-expectations (~> 3.4.0)
123
- rspec-mocks (~> 3.4.0)
124
- rspec-core (3.4.4)
125
- rspec-support (~> 3.4.0)
126
- rspec-expectations (3.4.0)
127
- diff-lcs (>= 1.2.0, < 2.0)
128
- rspec-support (~> 3.4.0)
129
- rspec-mocks (3.4.1)
130
- diff-lcs (>= 1.2.0, < 2.0)
131
- rspec-support (~> 3.4.0)
132
- rspec-support (3.4.1)
133
- rufus-scheduler (3.4.2)
134
- et-orbi (~> 1.0)
135
- sinatra (2.0.0.beta2)
136
- mustermann (= 1.0.0.beta2)
137
- rack (~> 2.0)
138
- rack-protection (= 2.0.0.beta2)
139
- tilt (~> 2.0)
140
- sinatra-contrib (2.0.0.beta2)
141
- backports (>= 2.0)
142
- multi_json
143
- mustermann (= 1.0.0.beta2)
144
- rack-protection (= 2.0.0.beta2)
145
- rack-test
146
- sinatra (= 2.0.0.beta2)
147
- tilt (>= 1.3, < 3)
148
- slop (3.6.0)
149
- sprockets (3.7.1)
150
- concurrent-ruby (~> 1.0)
151
- rack (> 1, < 3)
152
- sprockets-rails (3.2.0)
153
- actionpack (>= 4.0)
154
- activesupport (>= 4.0)
155
- sprockets (>= 3.0.0)
156
- thor (0.19.4)
157
- thread_safe (0.3.6)
158
- tilt (2.0.8)
159
- timecop (0.7.1)
160
- tzinfo (1.2.3)
161
- thread_safe (~> 0.1)
162
- websocket-driver (0.6.5)
163
- websocket-extensions (>= 0.1.0)
164
- websocket-extensions (0.1.2)
165
- wwtd (1.3.0)
166
-
167
- PLATFORMS
168
- ruby
169
-
170
- DEPENDENCIES
171
- bump
172
- byebug
173
- database_cleaner (= 1.6.1)
174
- inst-jobs!
175
- pg
176
- pry
177
- rack-test
178
- rails (~> 5.0.0)
179
- rake
180
- rspec (= 3.4.0)
181
- sinatra (= 2.0.0.beta2)
182
- sinatra-contrib (= 2.0.0.beta2)
183
- timecop (= 0.7.1)
184
- wwtd (~> 1.3.0)
185
-
186
- BUNDLED WITH
187
- 1.15.3
@@ -1,187 +0,0 @@
1
- PATH
2
- remote: ../..
3
- specs:
4
- inst-jobs (0.13.3)
5
- after_transaction_commit (~> 1.0)
6
- rails (>= 4.2)
7
- redis (> 3.0)
8
- redis-scripting (~> 1.0.1)
9
- rufus-scheduler (~> 3.4)
10
-
11
- GEM
12
- remote: https://rubygems.org/
13
- specs:
14
- actioncable (5.1.1)
15
- actionpack (= 5.1.1)
16
- nio4r (~> 2.0)
17
- websocket-driver (~> 0.6.1)
18
- actionmailer (5.1.1)
19
- actionpack (= 5.1.1)
20
- actionview (= 5.1.1)
21
- activejob (= 5.1.1)
22
- mail (~> 2.5, >= 2.5.4)
23
- rails-dom-testing (~> 2.0)
24
- actionpack (5.1.1)
25
- actionview (= 5.1.1)
26
- activesupport (= 5.1.1)
27
- rack (~> 2.0)
28
- rack-test (~> 0.6.3)
29
- rails-dom-testing (~> 2.0)
30
- rails-html-sanitizer (~> 1.0, >= 1.0.2)
31
- actionview (5.1.1)
32
- activesupport (= 5.1.1)
33
- builder (~> 3.1)
34
- erubi (~> 1.4)
35
- rails-dom-testing (~> 2.0)
36
- rails-html-sanitizer (~> 1.0, >= 1.0.3)
37
- activejob (5.1.1)
38
- activesupport (= 5.1.1)
39
- globalid (>= 0.3.6)
40
- activemodel (5.1.1)
41
- activesupport (= 5.1.1)
42
- activerecord (5.1.1)
43
- activemodel (= 5.1.1)
44
- activesupport (= 5.1.1)
45
- arel (~> 8.0)
46
- activesupport (5.1.1)
47
- concurrent-ruby (~> 1.0, >= 1.0.2)
48
- i18n (~> 0.7)
49
- minitest (~> 5.1)
50
- tzinfo (~> 1.1)
51
- after_transaction_commit (1.1.2)
52
- activerecord (>= 4.0)
53
- arel (8.0.0)
54
- backports (3.7.0)
55
- builder (3.2.3)
56
- bump (0.5.3)
57
- byebug (9.0.6)
58
- coderay (1.1.1)
59
- concurrent-ruby (1.0.5)
60
- database_cleaner (1.6.1)
61
- diff-lcs (1.3)
62
- erubi (1.6.0)
63
- et-orbi (1.0.3)
64
- tzinfo
65
- globalid (0.4.0)
66
- activesupport (>= 4.2.0)
67
- i18n (0.8.4)
68
- loofah (2.0.3)
69
- nokogiri (>= 1.5.9)
70
- mail (2.6.6)
71
- mime-types (>= 1.16, < 4)
72
- method_source (0.8.2)
73
- mime-types (3.1)
74
- mime-types-data (~> 3.2015)
75
- mime-types-data (3.2016.0521)
76
- mini_portile2 (2.2.0)
77
- minitest (5.10.2)
78
- multi_json (1.12.1)
79
- mustermann (1.0.0.beta2)
80
- nio4r (2.1.0)
81
- nokogiri (1.8.0)
82
- mini_portile2 (~> 2.2.0)
83
- pg (0.21.0)
84
- pry (0.10.4)
85
- coderay (~> 1.1.0)
86
- method_source (~> 0.8.1)
87
- slop (~> 3.4)
88
- rack (2.0.3)
89
- rack-protection (2.0.0.beta2)
90
- rack
91
- rack-test (0.6.3)
92
- rack (>= 1.0)
93
- rails (5.1.1)
94
- actioncable (= 5.1.1)
95
- actionmailer (= 5.1.1)
96
- actionpack (= 5.1.1)
97
- actionview (= 5.1.1)
98
- activejob (= 5.1.1)
99
- activemodel (= 5.1.1)
100
- activerecord (= 5.1.1)
101
- activesupport (= 5.1.1)
102
- bundler (>= 1.3.0, < 2.0)
103
- railties (= 5.1.1)
104
- sprockets-rails (>= 2.0.0)
105
- rails-dom-testing (2.0.3)
106
- activesupport (>= 4.2.0)
107
- nokogiri (>= 1.6)
108
- rails-html-sanitizer (1.0.3)
109
- loofah (~> 2.0)
110
- railties (5.1.1)
111
- actionpack (= 5.1.1)
112
- activesupport (= 5.1.1)
113
- method_source
114
- rake (>= 0.8.7)
115
- thor (>= 0.18.1, < 2.0)
116
- rake (12.0.0)
117
- redis (3.3.3)
118
- redis-scripting (1.0.1)
119
- redis (>= 3.0)
120
- rspec (3.4.0)
121
- rspec-core (~> 3.4.0)
122
- rspec-expectations (~> 3.4.0)
123
- rspec-mocks (~> 3.4.0)
124
- rspec-core (3.4.4)
125
- rspec-support (~> 3.4.0)
126
- rspec-expectations (3.4.0)
127
- diff-lcs (>= 1.2.0, < 2.0)
128
- rspec-support (~> 3.4.0)
129
- rspec-mocks (3.4.1)
130
- diff-lcs (>= 1.2.0, < 2.0)
131
- rspec-support (~> 3.4.0)
132
- rspec-support (3.4.1)
133
- rufus-scheduler (3.4.0)
134
- et-orbi (~> 1.0)
135
- sinatra (2.0.0.beta2)
136
- mustermann (= 1.0.0.beta2)
137
- rack (~> 2.0)
138
- rack-protection (= 2.0.0.beta2)
139
- tilt (~> 2.0)
140
- sinatra-contrib (2.0.0.beta2)
141
- backports (>= 2.0)
142
- multi_json
143
- mustermann (= 1.0.0.beta2)
144
- rack-protection (= 2.0.0.beta2)
145
- rack-test
146
- sinatra (= 2.0.0.beta2)
147
- tilt (>= 1.3, < 3)
148
- slop (3.6.0)
149
- sprockets (3.7.1)
150
- concurrent-ruby (~> 1.0)
151
- rack (> 1, < 3)
152
- sprockets-rails (3.2.0)
153
- actionpack (>= 4.0)
154
- activesupport (>= 4.0)
155
- sprockets (>= 3.0.0)
156
- thor (0.19.4)
157
- thread_safe (0.3.6)
158
- tilt (2.0.7)
159
- timecop (0.7.1)
160
- tzinfo (1.2.3)
161
- thread_safe (~> 0.1)
162
- websocket-driver (0.6.5)
163
- websocket-extensions (>= 0.1.0)
164
- websocket-extensions (0.1.2)
165
- wwtd (1.3.0)
166
-
167
- PLATFORMS
168
- ruby
169
-
170
- DEPENDENCIES
171
- bump
172
- byebug
173
- database_cleaner (= 1.6.1)
174
- inst-jobs!
175
- pg
176
- pry
177
- rack-test
178
- rails (~> 5.1.0)
179
- rake
180
- rspec (= 3.4.0)
181
- sinatra (= 2.0.0.beta2)
182
- sinatra-contrib (= 2.0.0.beta2)
183
- timecop (= 0.7.1)
184
- wwtd (~> 1.3.0)
185
-
186
- BUNDLED WITH
187
- 1.14.6