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 +4 -4
- data/lib/delayed/backend/active_record.rb +8 -1
- data/lib/delayed/backend/redis/job.rb +10 -2
- data/lib/delayed/periodic.rb +0 -2
- data/lib/delayed/settings.rb +9 -0
- data/lib/delayed/version.rb +1 -1
- data/lib/delayed/worker/consul_health_check.rb +108 -0
- data/lib/delayed/worker/health_check.rb +57 -0
- data/lib/delayed/worker/null_health_check.rb +11 -0
- data/lib/delayed/worker.rb +18 -3
- data/lib/delayed_job.rb +5 -0
- data/spec/delayed/worker/consul_health_check_spec.rb +74 -0
- data/spec/delayed/worker/health_check_spec.rb +98 -0
- data/spec/shared/shared_backend.rb +13 -0
- metadata +24 -9
- data/spec/gemfiles/42.gemfile.lock +0 -182
- data/spec/gemfiles/50.gemfile.lock +0 -187
- data/spec/gemfiles/51.gemfile.lock +0 -187
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e485941f6b24b6f88e18b37c1b25e2cab3862630
|
4
|
+
data.tar.gz: 8f753f31b331870b59a226e65822619da4429ab1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 =
|
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
|
-
|
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
|
data/lib/delayed/periodic.rb
CHANGED
@@ -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
|
data/lib/delayed/settings.rb
CHANGED
@@ -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
|
data/lib/delayed/version.rb
CHANGED
@@ -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
|
data/lib/delayed/worker.rb
CHANGED
@@ -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.
|
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-
|
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.
|
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
|