inst-jobs 2.0.0 → 3.0.0

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.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/db/migrate/20101216224513_create_delayed_jobs.rb +9 -7
  3. data/db/migrate/20110531144916_cleanup_delayed_jobs_indexes.rb +8 -13
  4. data/db/migrate/20110610213249_optimize_delayed_jobs.rb +8 -8
  5. data/db/migrate/20110831210257_add_delayed_jobs_next_in_strand.rb +25 -25
  6. data/db/migrate/20120510004759_delayed_jobs_delete_trigger_lock_for_update.rb +4 -8
  7. data/db/migrate/20120531150712_drop_psql_jobs_pop_fn.rb +1 -3
  8. data/db/migrate/20120607164022_delayed_jobs_use_advisory_locks.rb +11 -15
  9. data/db/migrate/20120607181141_index_jobs_on_locked_by.rb +1 -1
  10. data/db/migrate/20120608191051_add_jobs_run_at_index.rb +2 -2
  11. data/db/migrate/20120927184213_change_delayed_jobs_handler_to_text.rb +1 -1
  12. data/db/migrate/20140505215510_copy_failed_jobs_original_id.rb +2 -3
  13. data/db/migrate/20150807133223_add_max_concurrent_to_jobs.rb +9 -13
  14. data/db/migrate/20151210162949_improve_max_concurrent.rb +4 -8
  15. data/db/migrate/20161206323555_add_back_default_string_limits_jobs.rb +3 -2
  16. data/db/migrate/20181217155351_speed_up_max_concurrent_triggers.rb +13 -17
  17. data/db/migrate/20200330230722_add_id_to_get_delayed_jobs_index.rb +8 -8
  18. data/db/migrate/20200824222232_speed_up_max_concurrent_delete_trigger.rb +72 -77
  19. data/db/migrate/20200825011002_add_strand_order_override.rb +93 -97
  20. data/db/migrate/20210809145804_add_n_strand_index.rb +12 -0
  21. data/db/migrate/20210812210128_add_singleton_column.rb +200 -0
  22. data/db/migrate/20210917232626_add_delete_conflicting_singletons_before_unlock_trigger.rb +27 -0
  23. data/db/migrate/20210928174754_fix_singleton_condition_in_before_insert.rb +56 -0
  24. data/db/migrate/20210929204903_update_conflicting_singleton_function_to_use_index.rb +27 -0
  25. data/exe/inst_jobs +3 -2
  26. data/lib/delayed/backend/active_record.rb +211 -168
  27. data/lib/delayed/backend/base.rb +110 -72
  28. data/lib/delayed/batch.rb +11 -9
  29. data/lib/delayed/cli.rb +98 -84
  30. data/lib/delayed/core_ext/kernel.rb +4 -2
  31. data/lib/delayed/daemon.rb +70 -74
  32. data/lib/delayed/job_tracking.rb +26 -25
  33. data/lib/delayed/lifecycle.rb +27 -23
  34. data/lib/delayed/log_tailer.rb +17 -17
  35. data/lib/delayed/logging.rb +13 -16
  36. data/lib/delayed/message_sending.rb +43 -52
  37. data/lib/delayed/performable_method.rb +6 -8
  38. data/lib/delayed/periodic.rb +72 -68
  39. data/lib/delayed/plugin.rb +2 -4
  40. data/lib/delayed/pool.rb +205 -168
  41. data/lib/delayed/server/helpers.rb +6 -6
  42. data/lib/delayed/server.rb +51 -54
  43. data/lib/delayed/settings.rb +94 -81
  44. data/lib/delayed/testing.rb +21 -22
  45. data/lib/delayed/version.rb +1 -1
  46. data/lib/delayed/work_queue/in_process.rb +21 -17
  47. data/lib/delayed/work_queue/parent_process/client.rb +55 -53
  48. data/lib/delayed/work_queue/parent_process/server.rb +245 -207
  49. data/lib/delayed/work_queue/parent_process.rb +52 -53
  50. data/lib/delayed/worker/consul_health_check.rb +32 -33
  51. data/lib/delayed/worker/health_check.rb +34 -26
  52. data/lib/delayed/worker/null_health_check.rb +3 -1
  53. data/lib/delayed/worker/process_helper.rb +8 -9
  54. data/lib/delayed/worker.rb +272 -241
  55. data/lib/delayed/yaml_extensions.rb +12 -10
  56. data/lib/delayed_job.rb +37 -37
  57. data/lib/inst-jobs.rb +1 -1
  58. data/spec/active_record_job_spec.rb +143 -139
  59. data/spec/delayed/cli_spec.rb +7 -7
  60. data/spec/delayed/daemon_spec.rb +10 -9
  61. data/spec/delayed/message_sending_spec.rb +16 -9
  62. data/spec/delayed/periodic_spec.rb +14 -21
  63. data/spec/delayed/server_spec.rb +38 -38
  64. data/spec/delayed/settings_spec.rb +26 -25
  65. data/spec/delayed/work_queue/in_process_spec.rb +7 -8
  66. data/spec/delayed/work_queue/parent_process/client_spec.rb +17 -12
  67. data/spec/delayed/work_queue/parent_process/server_spec.rb +117 -41
  68. data/spec/delayed/work_queue/parent_process_spec.rb +21 -23
  69. data/spec/delayed/worker/consul_health_check_spec.rb +37 -50
  70. data/spec/delayed/worker/health_check_spec.rb +60 -52
  71. data/spec/delayed/worker_spec.rb +44 -21
  72. data/spec/sample_jobs.rb +45 -15
  73. data/spec/shared/delayed_batch.rb +74 -67
  74. data/spec/shared/delayed_method.rb +143 -102
  75. data/spec/shared/performable_method.rb +39 -38
  76. data/spec/shared/shared_backend.rb +550 -437
  77. data/spec/shared/testing.rb +14 -14
  78. data/spec/shared/worker.rb +156 -148
  79. data/spec/shared_jobs_specs.rb +13 -13
  80. data/spec/spec_helper.rb +53 -55
  81. metadata +148 -82
  82. data/lib/delayed/backend/redis/bulk_update.lua +0 -50
  83. data/lib/delayed/backend/redis/destroy_job.lua +0 -2
  84. data/lib/delayed/backend/redis/enqueue.lua +0 -29
  85. data/lib/delayed/backend/redis/fail_job.lua +0 -5
  86. data/lib/delayed/backend/redis/find_available.lua +0 -3
  87. data/lib/delayed/backend/redis/functions.rb +0 -59
  88. data/lib/delayed/backend/redis/get_and_lock_next_available.lua +0 -17
  89. data/lib/delayed/backend/redis/includes/jobs_common.lua +0 -203
  90. data/lib/delayed/backend/redis/job.rb +0 -535
  91. data/lib/delayed/backend/redis/set_running.lua +0 -5
  92. data/lib/delayed/backend/redis/tickle_strand.lua +0 -2
  93. data/spec/gemfiles/42.gemfile +0 -7
  94. data/spec/gemfiles/50.gemfile +0 -7
  95. data/spec/gemfiles/51.gemfile +0 -7
  96. data/spec/gemfiles/52.gemfile +0 -7
  97. data/spec/gemfiles/60.gemfile +0 -7
  98. data/spec/redis_job_spec.rb +0 -148
@@ -1,32 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require "spec_helper"
4
4
 
5
- RSpec.describe Delayed::WorkQueue::ParentProcess::Server do
6
- class JobClass
7
- attr_reader :id
5
+ class JobClass
6
+ attr_reader :id
8
7
 
9
- def initialize
10
- @id = rand
11
- end
8
+ def initialize
9
+ @id = rand
10
+ end
12
11
 
13
- def ==(other)
14
- self.id == other.id
15
- end
12
+ def ==(other)
13
+ id == other.id
16
14
  end
15
+ end
16
+
17
+ RSpec.describe Delayed::WorkQueue::ParentProcess::Server do
18
+ subject { described_class.new(listen_socket) }
17
19
 
18
20
  let(:parent) { Delayed::WorkQueue::ParentProcess.new }
19
- let(:subject) { described_class.new(listen_socket) }
20
21
  let(:listen_socket) { Socket.unix_server_socket(parent.server_address) }
21
22
  let(:job) { JobClass.new }
22
23
  let(:worker_config) { { queue: "queue_name", min_priority: 1, max_priority: 2 } }
23
24
  let(:args) { ["worker_name", worker_config] }
24
25
  let(:job_args) { [["worker_name"], "queue_name", 1, 2, hash_including(prefetch: 4)] }
25
26
 
27
+ before do
28
+ Delayed::Worker.lifecycle.reset!
29
+ end
30
+
26
31
  before :all do
27
32
  Delayed.select_backend(Delayed::Backend::ActiveRecord::Job)
28
33
  Delayed::Settings.parent_process = {
29
- 'server_address' => '/tmp/inst-jobs-test.sock'
34
+ "server_address" => "/tmp/inst-jobs-test.sock"
30
35
  }
31
36
  end
32
37
 
@@ -34,27 +39,28 @@ RSpec.describe Delayed::WorkQueue::ParentProcess::Server do
34
39
  Delayed::Settings.parent_process = {}
35
40
  end
36
41
 
37
- after :each do
38
- File.unlink('/tmp/inst-jobs-test.sock') if File.exist?('/tmp/inst-jobs-test.sock')
42
+ after do
43
+ File.unlink("/tmp/inst-jobs-test.sock") if File.exist?("/tmp/inst-jobs-test.sock")
44
+ Delayed::Worker.lifecycle.reset!
39
45
  end
40
46
 
41
- it 'accepts new clients' do
42
- client = Socket.unix(subject.listen_socket.local_address.unix_path)
47
+ it "accepts new clients" do
48
+ Socket.unix(subject.listen_socket.local_address.unix_path)
43
49
  expect { subject.run_once }.to change(subject, :connected_clients).by(1)
44
50
  end
45
51
 
46
- it 'queries the queue on client request' do
52
+ it "queries the queue on client request" do
47
53
  client = Socket.unix(subject.listen_socket.local_address.unix_path)
48
54
  subject.run_once
49
55
 
50
- expect(Delayed::Job).to receive(:get_and_lock_next_available).with(*job_args).and_return('worker_name' => job)
56
+ expect(Delayed::Job).to receive(:get_and_lock_next_available).with(*job_args).and_return("worker_name" => job)
51
57
  Marshal.dump(args, client)
52
58
  subject.run_once
53
59
  expect(client).to be_ready
54
60
  expect(Marshal.load(client)).to eq(job)
55
61
  end
56
62
 
57
- it 'can pop multiple jobs at once' do
63
+ it "can pop multiple jobs at once" do
58
64
  client1 = Socket.unix(subject.listen_socket.local_address.unix_path)
59
65
  subject.run_once
60
66
  client2 = Socket.unix(subject.listen_socket.local_address.unix_path)
@@ -62,8 +68,8 @@ RSpec.describe Delayed::WorkQueue::ParentProcess::Server do
62
68
 
63
69
  job1 = JobClass.new
64
70
  job2 = JobClass.new
65
- job_args = [["worker_name1", "worker_name2"], "queue_name", 1, 2, hash_including(prefetch: 3)]
66
- jobs = { 'worker_name1' => job1, 'worker_name2' => job2 }
71
+ job_args = [%w[worker_name1 worker_name2], "queue_name", 1, 2, hash_including(prefetch: 3)]
72
+ jobs = { "worker_name1" => job1, "worker_name2" => job2 }
67
73
 
68
74
  expect(Delayed::Job).to receive(:get_and_lock_next_available).with(*job_args).and_return(jobs)
69
75
  Marshal.dump(["worker_name1", worker_config], client1)
@@ -73,30 +79,78 @@ RSpec.describe Delayed::WorkQueue::ParentProcess::Server do
73
79
  expect(Marshal.load(client2)).to eq(job2)
74
80
  end
75
81
 
76
- it 'will prefetch and use jobs' do
82
+ it "will prefetch and use jobs" do
77
83
  client = Socket.unix(subject.listen_socket.local_address.unix_path)
78
84
  subject.run_once
79
85
 
80
- allow(subject).to receive(:prefetch_owner).and_return('work_queue:X')
81
- job_args = [["worker_name1"], "queue_name", 1, 2, prefetch: 4, prefetch_owner: 'work_queue:X', forced_latency: 6.0]
82
- job2 = Delayed::Job.new(:tag => 'tag')
83
- job2.create_and_lock!('work_queue:X')
84
- job3 = Delayed::Job.new(:tag => 'tag')
85
- job3.create_and_lock!('work_queue:X')
86
- jobs = { 'worker_name1' => job, 'work_queue:X' => [job2, job3]}
86
+ allow(subject).to receive(:prefetch_owner).and_return("work_queue:X")
87
+ job_args = [["worker_name1"], "queue_name", 1, 2,
88
+ { prefetch: 4, prefetch_owner: "work_queue:X", forced_latency: 6.0 }]
89
+ job2 = Delayed::Job.new(tag: "tag")
90
+ job2.create_and_lock!("work_queue:X")
91
+ job3 = Delayed::Job.new(tag: "tag")
92
+ job3.create_and_lock!("work_queue:X")
93
+ jobs = { "worker_name1" => job, "work_queue:X" => [job2, job3] }
87
94
 
88
95
  expect(Delayed::Job).to receive(:get_and_lock_next_available).once.with(*job_args).and_return(jobs)
89
96
  Marshal.dump(["worker_name1", worker_config], client)
90
97
  subject.run_once
91
- expect(subject).to_not be_all_workers_idle
98
+ expect(subject).not_to be_all_workers_idle
92
99
  expect(Marshal.load(client)).to eq(job)
93
100
 
94
101
  Marshal.dump(["worker_name1", worker_config], client)
95
102
  subject.run_once
96
- expect(subject).to_not be_all_workers_idle
103
+ expect(subject).not_to be_all_workers_idle
97
104
  expect(Marshal.load(client)).to eq(job2)
98
105
  end
99
106
 
107
+ context "prefetched job unlocking" do
108
+ let(:job_args) do
109
+ [["worker_name1"], "queue_name", 1, 2,
110
+ { prefetch: 4, prefetch_owner: "prefetch:work_queue:X", forced_latency: 6.0 }]
111
+ end
112
+ let(:job2) { Delayed::Job.new(tag: "tag").tap { |j| j.create_and_lock!("prefetch:work_queue:X") } }
113
+ let(:job3) { Delayed::Job.new(tag: "tag").tap { |j| j.create_and_lock!("prefetch:work_queue:X") } }
114
+
115
+ before do
116
+ client = Socket.unix(subject.listen_socket.local_address.unix_path)
117
+ subject.run_once
118
+
119
+ jobs = { "worker_name1" => job, "prefetch:work_queue:X" => [job2, job3] }
120
+ allow(subject).to receive(:prefetch_owner).and_return("prefetch:work_queue:X")
121
+ allow(Delayed::Job).to receive(:get_and_lock_next_available).once.with(*job_args).and_return(jobs)
122
+ Marshal.dump(["worker_name1", worker_config], client)
123
+ subject.run_once
124
+ end
125
+
126
+ it "doesn't unlock anything if nothing is timed out" do
127
+ expect(Delayed::Job).not_to receive(:advisory_lock)
128
+ expect(Delayed::Job).not_to receive(:unlock)
129
+ subject.unlock_timed_out_prefetched_jobs
130
+ end
131
+
132
+ it "unlocks timed out prefetched jobs" do
133
+ allow(Delayed::Settings).to receive(:parent_process).and_return(prefetched_jobs_timeout: -1)
134
+ expect(Delayed::Job).to receive(:unlock).with([job2, job3])
135
+ subject.unlock_timed_out_prefetched_jobs
136
+ expect(subject.instance_variable_get(:@prefetched_jobs).values.sum(&:length)).to eq 0
137
+ end
138
+
139
+ it "fails gracefully if the lock times out" do
140
+ allow(Delayed::Settings).to receive(:parent_process).and_return(prefetched_jobs_timeout: -1)
141
+ expect(Delayed::Job).not_to receive(:unlock)
142
+ expect(Delayed::Job).to receive(:advisory_lock).and_raise(ActiveRecord::QueryCanceled)
143
+ subject.unlock_timed_out_prefetched_jobs
144
+ expect(subject.instance_variable_get(:@prefetched_jobs).values.sum(&:length)).to eq 2
145
+ end
146
+
147
+ it "unlocks all jobs" do
148
+ expect(Delayed::Job).to receive(:unlock).with([job2, job3])
149
+ subject.unlock_all_prefetched_jobs
150
+ expect(subject.instance_variable_get(:@prefetched_jobs).values.sum(&:length)).to eq 0
151
+ end
152
+ end
153
+
100
154
  it "doesn't respond immediately if there are no jobs available" do
101
155
  client = Socket.unix(subject.listen_socket.local_address.unix_path)
102
156
  subject.run_once
@@ -107,7 +161,10 @@ RSpec.describe Delayed::WorkQueue::ParentProcess::Server do
107
161
  expect(client).not_to be_ready
108
162
 
109
163
  # next time around, return the result
110
- expect(Delayed::Job).to receive(:get_and_lock_next_available).with(*job_args).and_return('worker_name' => job).ordered
164
+ expect(Delayed::Job).to receive(:get_and_lock_next_available)
165
+ .with(*job_args)
166
+ .and_return("worker_name" => job)
167
+ .ordered
111
168
  allow(Delayed::Settings).to receive(:sleep_delay).and_return(0)
112
169
  allow(Delayed::Settings).to receive(:sleep_delay_stagger).and_return(0)
113
170
  subject.run_once
@@ -115,7 +172,7 @@ RSpec.describe Delayed::WorkQueue::ParentProcess::Server do
115
172
  expect(Marshal.load(client)).to eq(job)
116
173
  end
117
174
 
118
- it 'drops the client on i/o error' do
175
+ it "drops the client on i/o error" do
119
176
  client = Socket.unix(subject.listen_socket.local_address.unix_path)
120
177
  subject.run_once
121
178
 
@@ -125,7 +182,7 @@ RSpec.describe Delayed::WorkQueue::ParentProcess::Server do
125
182
  expect { subject.run_once }.to change(subject, :connected_clients).by(-1)
126
183
  end
127
184
 
128
- it 'drops the client when the client disconnects' do
185
+ it "drops the client when the client disconnects" do
129
186
  client = Socket.unix(subject.listen_socket.local_address.unix_path)
130
187
  subject.run_once
131
188
 
@@ -138,7 +195,7 @@ RSpec.describe Delayed::WorkQueue::ParentProcess::Server do
138
195
  expect(subject.instance_variable_get(:@waiting_clients).first.last).to eq []
139
196
  end
140
197
 
141
- it 'drops the client when a write fails' do
198
+ it "drops the client when a write fails" do
142
199
  client = Socket.unix(subject.listen_socket.local_address.unix_path)
143
200
  subject.run_once
144
201
 
@@ -151,7 +208,7 @@ RSpec.describe Delayed::WorkQueue::ParentProcess::Server do
151
208
  # don't let the server see the close and process it there; we want to check a failure later
152
209
  expect(subject).to receive(:handle_request).with(server_client_socket)
153
210
 
154
- expect(Delayed::Job).to receive(:get_and_lock_next_available).with(*job_args).and_return('worker_name' => job)
211
+ expect(Delayed::Job).to receive(:get_and_lock_next_available).with(*job_args).and_return("worker_name" => job)
155
212
  # the job gets unlocked
156
213
  expect(Delayed::Job).to receive(:unlock).with([job])
157
214
  subject.run_once
@@ -161,14 +218,14 @@ RSpec.describe Delayed::WorkQueue::ParentProcess::Server do
161
218
  expect(subject.instance_variable_get(:@waiting_clients).first.last).to eq []
162
219
  end
163
220
 
164
- it 'tracks when clients are idle' do
221
+ it "tracks when clients are idle" do
165
222
  expect(subject.all_workers_idle?).to be(true)
166
223
 
167
224
  client = Socket.unix(subject.listen_socket.local_address.unix_path)
168
225
  subject.run_once
169
226
  expect(subject.all_workers_idle?).to be(true)
170
227
 
171
- expect(Delayed::Job).to receive(:get_and_lock_next_available).with(*job_args).and_return('worker_name' => job)
228
+ expect(Delayed::Job).to receive(:get_and_lock_next_available).with(*job_args).and_return("worker_name" => job)
172
229
  Marshal.dump(args, client)
173
230
  subject.run_once
174
231
  expect(subject.all_workers_idle?).to be(false)
@@ -179,7 +236,7 @@ RSpec.describe Delayed::WorkQueue::ParentProcess::Server do
179
236
  expect(subject.all_workers_idle?).to be(true)
180
237
  end
181
238
 
182
- it 'triggers the lifecycle event around the pop' do
239
+ it "triggers the lifecycle event around the pop" do
183
240
  called = false
184
241
  client = Socket.unix(subject.listen_socket.local_address.unix_path)
185
242
  subject.run_once
@@ -187,7 +244,7 @@ RSpec.describe Delayed::WorkQueue::ParentProcess::Server do
187
244
  Delayed::Worker.lifecycle.around(:work_queue_pop) do |queue, &cb|
188
245
  expect(subject.all_workers_idle?).to be(true)
189
246
  expect(queue).to eq(subject)
190
- expect(Delayed::Job).to receive(:get_and_lock_next_available).with(*job_args).and_return('worker_name' => job)
247
+ expect(Delayed::Job).to receive(:get_and_lock_next_available).with(*job_args).and_return("worker_name" => job)
191
248
  called = true
192
249
  res = cb.call(queue)
193
250
  expect(subject.all_workers_idle?).to be(false)
@@ -200,5 +257,24 @@ RSpec.describe Delayed::WorkQueue::ParentProcess::Server do
200
257
  expect(Marshal.load(client)).to eq(job)
201
258
  expect(called).to eq(true)
202
259
  end
203
- end
204
260
 
261
+ it "deletes the correct worker when transferring jobs" do
262
+ client1 = Socket.unix(subject.listen_socket.local_address.unix_path)
263
+ client2 = Socket.unix(subject.listen_socket.local_address.unix_path)
264
+ subject.run_once
265
+ subject.run_once
266
+
267
+ Marshal.dump(args, client1)
268
+ Marshal.dump(["worker_name2", worker_config], client2)
269
+ subject.run_once
270
+ subject.run_once
271
+
272
+ waiting_clients = subject.instance_variable_get(:@waiting_clients)
273
+ expect(waiting_clients.first.last.length).to eq 2
274
+
275
+ expect(Delayed::Job).to receive(:get_and_lock_next_available).and_return("worker_name" => job,
276
+ "worker_name2" => job)
277
+ subject.run_once
278
+ expect(waiting_clients.first.last).to be_empty
279
+ end
280
+ end
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
- require 'fileutils'
3
+ require "spec_helper"
4
+ require "fileutils"
5
5
 
6
6
  RSpec.describe Delayed::WorkQueue::ParentProcess do
7
7
  before :all do
8
- FileUtils.mkdir_p(Delayed::Settings.expand_rails_path('tmp'))
8
+ FileUtils.mkdir_p(Delayed::Settings.expand_rails_path("tmp"))
9
9
  Delayed.select_backend(Delayed::Backend::ActiveRecord::Job)
10
10
  Delayed::Settings.parent_process = {
11
- 'server_address' => '/tmp/inst-jobs-test.sock'
11
+ "server_address" => "/tmp/inst-jobs-test.sock"
12
12
  }
13
13
  end
14
14
 
@@ -16,43 +16,41 @@ RSpec.describe Delayed::WorkQueue::ParentProcess do
16
16
  Delayed::Settings.parent_process = {}
17
17
  end
18
18
 
19
- after :each do
20
- File.unlink('/tmp/inst-jobs-test.sock') if File.exist?('/tmp/inst-jobs-test.sock')
19
+ after do
20
+ File.unlink("/tmp/inst-jobs-test.sock") if File.exist?("/tmp/inst-jobs-test.sock")
21
21
  Delayed::Worker.lifecycle.reset!
22
22
  end
23
23
 
24
- let(:subject) { described_class.new }
25
-
26
- describe '#initalize(config = Settings.parent_process)' do
27
- it 'must expand a relative path to be within the Rails root' do
28
- queue = described_class.new('server_address' => 'tmp/foo.sock')
29
- expect(queue.server_address).to eq Delayed::Settings.expand_rails_path('tmp/foo.sock')
24
+ describe "#initalize(config = Settings.parent_process)" do
25
+ it "must expand a relative path to be within the Rails root" do
26
+ queue = described_class.new("server_address" => "tmp/foo.sock")
27
+ expect(queue.server_address).to eq Delayed::Settings.expand_rails_path("tmp/foo.sock")
30
28
  end
31
29
 
32
- it 'must add a file name when a relative path to a directory is supplied' do
33
- queue = described_class.new('server_address' => 'tmp')
34
- expect(queue.server_address).to eq Delayed::Settings.expand_rails_path('tmp/inst-jobs.sock')
30
+ it "must add a file name when a relative path to a directory is supplied" do
31
+ queue = described_class.new("server_address" => "tmp")
32
+ expect(queue.server_address).to eq Delayed::Settings.expand_rails_path("tmp/inst-jobs.sock")
35
33
  end
36
34
 
37
- it 'must capture a full absolute path' do
38
- queue = described_class.new('server_address' => '/tmp/foo.sock')
39
- expect(queue.server_address).to eq '/tmp/foo.sock'
35
+ it "must capture a full absolute path" do
36
+ queue = described_class.new("server_address" => "/tmp/foo.sock")
37
+ expect(queue.server_address).to eq "/tmp/foo.sock"
40
38
  end
41
39
 
42
- it 'must add a file name when an absolute path to a directory is supplied' do
43
- queue = described_class.new('server_address' => '/tmp')
44
- expect(queue.server_address).to eq '/tmp/inst-jobs.sock'
40
+ it "must add a file name when an absolute path to a directory is supplied" do
41
+ queue = described_class.new("server_address" => "/tmp")
42
+ expect(queue.server_address).to eq "/tmp/inst-jobs.sock"
45
43
  end
46
44
  end
47
45
 
48
- it 'generates a server listening on a valid unix socket' do
46
+ it "generates a server listening on a valid unix socket" do
49
47
  server = subject.server
50
48
  expect(server).to be_a(Delayed::WorkQueue::ParentProcess::Server)
51
49
  expect(server.listen_socket.local_address.unix?).to be(true)
52
50
  expect { server.listen_socket.accept_nonblock }.to raise_error(IO::WaitReadable)
53
51
  end
54
52
 
55
- it 'generates a client connected to the server unix socket' do
53
+ it "generates a client connected to the server unix socket" do
56
54
  server = subject.server
57
55
  client = subject.client
58
56
  expect(client).to be_a(Delayed::WorkQueue::ParentProcess::Client)
@@ -1,76 +1,63 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
4
- require 'imperium'
3
+ require "spec_helper"
5
4
 
6
5
  RSpec.describe Delayed::Worker::ConsulHealthCheck do
7
- let(:health_check) { Delayed::Worker::ConsulHealthCheck.new(worker_name: 'foobar') }
6
+ let(:health_check) { described_class.new(worker_name: "foobar") }
8
7
 
9
- # can't use a verifying double for the response because the methods we're
10
- # tryig to stub are actually on HTTP::Message
11
- let(:response) { double('Imperium::Response') }
12
- let(:agent_client) { instance_double(Imperium::Agent) }
13
-
14
- before do
15
- allow(Imperium::Agent).to receive(:default_client).and_return(agent_client)
16
- end
17
-
18
- describe '#initialize' do
19
- it 'must use the default agent client when the config is mostly empty' do
20
- check = Delayed::Worker::ConsulHealthCheck.new(worker_name: 'foobar')
21
- expect(check.agent_client).to eq Imperium::Agent.default_client
8
+ describe "#initialize" do
9
+ it "must use a default service client when the config is mostly empty" do
10
+ check = described_class.new(worker_name: "foobar")
11
+ expect(check.service_client.configuration.url.to_s).to eq "http://localhost:8500"
22
12
  end
23
13
 
24
- it 'must create a new agent API client when the config has relevant keys set' do
25
- check = Delayed::Worker::ConsulHealthCheck.new(worker_name: 'foobar', config: {url: 'http://consul.example.com:8500'})
26
- agent_client = check.agent_client
27
- expect(agent_client).to_not eq Imperium::Agent.default_client
28
- expect(agent_client.config.url.to_s).to eq 'http://consul.example.com:8500'
14
+ it "must create a new service API client when the config has relevant keys set" do
15
+ check = described_class.new(worker_name: "foobar",
16
+ config: { url: "http://consul.example.com:8500" })
17
+ service_client = check.service_client
18
+ expect(service_client.configuration.url.to_s).to eq "http://consul.example.com:8500"
29
19
  end
30
20
  end
31
21
 
32
- describe '#start' do
33
- it 'must register this process as a service with consul' do
34
- expect(response).to receive(:ok?).and_return(true)
35
- expect(agent_client).to receive(:register_service)
36
- .with(an_instance_of(Imperium::Service))
37
- .and_return(response)
22
+ describe "#start" do
23
+ it "must register this process as a service with consul" do
24
+ stub = stub_request(:put, "localhost:8500/v1/agent/service/register")
25
+ .with(body: hash_including({ id: "foobar" }))
26
+
38
27
  health_check.start
28
+
29
+ expect(stub).to have_been_requested
39
30
  end
40
31
 
32
+ it "must supply a args style check" do
33
+ stub = stub_request(:put, "localhost:8500/v1/agent/service/register")
34
+ .with(body: hash_including({ check: WebMock::API.hash_including({ args: anything }) }))
41
35
 
42
- it 'must supply a args style check' do
43
- allow(response).to receive(:ok?).and_return(true)
44
- allow(agent_client).to receive(:register_service) { |service|
45
- check = service.checks.first
46
- expect(check.args).to_not be_nil
47
- response
48
- }
49
36
  health_check.start
37
+
38
+ expect(stub).to have_been_requested
50
39
  end
51
40
 
52
- it 'must include the docker container id when the docker option is set to true' do
53
- local_health_check = Delayed::Worker::ConsulHealthCheck.new(
54
- worker_name: 'foobar',
55
- config: {docker: true}
41
+ it "must include the docker container id when the docker option is set to true" do
42
+ stub = stub_request(:put, "localhost:8500/v1/agent/service/register")
43
+ .with(body: hash_including({ check: WebMock::API.hash_including({ docker_container_id: anything }) }))
44
+
45
+ local_health_check = described_class.new(
46
+ worker_name: "foobar",
47
+ config: { docker: true }
56
48
  )
57
- allow(response).to receive(:ok?).and_return(true)
58
- allow(agent_client).to receive(:register_service) { |service|
59
- check = service.checks.first
60
- expect(check.docker_container_id).to_not be_nil
61
- response
62
- }
63
49
  local_health_check.start
50
+
51
+ expect(stub).to have_been_requested
64
52
  end
65
53
  end
66
54
 
67
- describe '#stop' do
68
- it 'must deregister the service from consul' do
69
- allow(response).to receive(:ok?).and_return(true)
70
- expect(agent_client).to receive(:deregister_service)
71
- .with(health_check.worker_name)
72
- .and_return(response)
55
+ describe "#stop" do
56
+ it "must deregister the service from consul" do
57
+ stub = stub_request(:put, "localhost:8500/v1/agent/service/deregister/foobar")
58
+
73
59
  health_check.stop
60
+ expect(stub).to have_been_requested
74
61
  end
75
62
  end
76
63
  end