taskinator 0.0.18 → 0.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/Gemfile.lock +28 -28
- data/README.md +29 -0
- data/Rakefile +5 -0
- data/bin/console +5 -0
- data/lib/taskinator/create_process_worker.rb +5 -2
- data/lib/taskinator/definition/builder.rb +12 -7
- data/lib/taskinator/definition.rb +36 -28
- data/lib/taskinator/executor.rb +4 -4
- data/lib/taskinator/job_worker.rb +5 -10
- data/lib/taskinator/logger.rb +1 -0
- data/lib/taskinator/persistence.rb +74 -36
- data/lib/taskinator/process.rb +75 -49
- data/lib/taskinator/queues/delayed_job.rb +1 -11
- data/lib/taskinator/queues/resque.rb +0 -15
- data/lib/taskinator/queues/sidekiq.rb +1 -14
- data/lib/taskinator/queues.rb +0 -5
- data/lib/taskinator/redis_connection.rb +1 -0
- data/lib/taskinator/task.rb +57 -57
- data/lib/taskinator/task_worker.rb +1 -8
- data/lib/taskinator/version.rb +1 -1
- data/lib/taskinator.rb +7 -6
- data/spec/examples/queue_adapter_examples.rb +0 -10
- data/spec/support/test_definition.rb +4 -0
- data/spec/support/test_flow.rb +2 -0
- data/spec/support/test_flows.rb +54 -3
- data/spec/support/test_queue.rb +41 -6
- data/spec/taskinator/create_process_worker_spec.rb +12 -3
- data/spec/taskinator/definition/builder_spec.rb +39 -9
- data/spec/taskinator/definition_spec.rb +19 -27
- data/spec/taskinator/executor_spec.rb +19 -1
- data/spec/taskinator/job_worker_spec.rb +0 -11
- data/spec/taskinator/persistence_spec.rb +122 -7
- data/spec/taskinator/process_spec.rb +39 -23
- data/spec/taskinator/queues/delayed_job_spec.rb +1 -19
- data/spec/taskinator/queues/resque_spec.rb +1 -22
- data/spec/taskinator/queues/sidekiq_spec.rb +1 -20
- data/spec/taskinator/task_spec.rb +160 -52
- data/spec/taskinator/task_worker_spec.rb +0 -17
- data/spec/taskinator/test_flows_spec.rb +43 -0
- metadata +2 -5
- data/lib/taskinator/process_worker.rb +0 -21
- data/spec/taskinator/process_worker_spec.rb +0 -51
@@ -74,20 +74,6 @@ describe Taskinator::Process do
|
|
74
74
|
subject.enqueue!
|
75
75
|
expect(subject.current_state.name).to eq(:enqueued)
|
76
76
|
}
|
77
|
-
|
78
|
-
it "should not enqueue if there aren't any tasks" do
|
79
|
-
expect {
|
80
|
-
subject.enqueue!
|
81
|
-
}.to change { Taskinator.queue.processes.length }.by(0)
|
82
|
-
end
|
83
|
-
|
84
|
-
it "should enqueue if there are tasks" do
|
85
|
-
allow(subject).to receive(:tasks).and_return([Object.new])
|
86
|
-
|
87
|
-
expect {
|
88
|
-
subject.enqueue!
|
89
|
-
}.to change { Taskinator.queue.processes.length }.by(1)
|
90
|
-
end
|
91
77
|
end
|
92
78
|
|
93
79
|
describe "#start!" do
|
@@ -155,7 +141,6 @@ describe Taskinator::Process do
|
|
155
141
|
subject.complete!
|
156
142
|
}
|
157
143
|
it {
|
158
|
-
expect(subject).to receive(:tasks_completed?) { true }
|
159
144
|
subject.start!
|
160
145
|
subject.complete!
|
161
146
|
expect(subject.current_state.name).to eq(:completed)
|
@@ -216,10 +201,6 @@ describe Taskinator::Process do
|
|
216
201
|
}
|
217
202
|
end
|
218
203
|
|
219
|
-
describe "#reload" do
|
220
|
-
it { expect(subject.reload).to_not be }
|
221
|
-
end
|
222
|
-
|
223
204
|
describe "#tasks_count" do
|
224
205
|
it {
|
225
206
|
expect(subject.tasks_count).to eq(0)
|
@@ -262,13 +243,31 @@ describe Taskinator::Process do
|
|
262
243
|
end
|
263
244
|
end
|
264
245
|
|
246
|
+
describe "#enqueue!" do
|
247
|
+
context "without tasks" do
|
248
|
+
it {
|
249
|
+
expect {
|
250
|
+
subject.enqueue!
|
251
|
+
}.to change { Taskinator.queue.tasks.length }.by(0)
|
252
|
+
}
|
253
|
+
end
|
254
|
+
|
255
|
+
it "delegates to the first task" do
|
256
|
+
task = double('task')
|
257
|
+
expect(task).to receive(:enqueue!)
|
258
|
+
allow(subject).to receive(:tasks).and_return([task])
|
259
|
+
|
260
|
+
subject.enqueue!
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
265
264
|
describe "#start!" do
|
266
265
|
it "executes the first task" do
|
267
266
|
tasks.each {|t| subject.tasks << t }
|
268
267
|
task1 = tasks[0]
|
269
268
|
|
270
269
|
expect(subject.tasks).to receive(:first).and_call_original
|
271
|
-
expect(task1).to receive(:
|
270
|
+
expect(task1).to receive(:start!)
|
272
271
|
|
273
272
|
subject.start!
|
274
273
|
end
|
@@ -295,7 +294,6 @@ describe Taskinator::Process do
|
|
295
294
|
tasks.each {|t| subject.tasks << t }
|
296
295
|
task2 = tasks[1]
|
297
296
|
|
298
|
-
expect(subject).to receive(:can_complete?) { true }
|
299
297
|
expect(subject).to receive(:complete!)
|
300
298
|
|
301
299
|
subject.task_completed(task2)
|
@@ -380,11 +378,30 @@ describe Taskinator::Process do
|
|
380
378
|
end
|
381
379
|
end
|
382
380
|
|
381
|
+
describe "#enqueue!" do
|
382
|
+
context "without tasks" do
|
383
|
+
it {
|
384
|
+
expect {
|
385
|
+
subject.enqueue!
|
386
|
+
}.to change { Taskinator.queue.tasks.length }.by(0)
|
387
|
+
}
|
388
|
+
end
|
389
|
+
|
390
|
+
it "delegates to all the tasks" do
|
391
|
+
tasks.each {|t|
|
392
|
+
subject.tasks << t
|
393
|
+
expect(t).to receive(:enqueue!)
|
394
|
+
}
|
395
|
+
|
396
|
+
subject.enqueue!
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
383
400
|
describe "#start!" do
|
384
401
|
it "executes all tasks" do
|
385
402
|
tasks.each {|t|
|
386
403
|
subject.tasks << t
|
387
|
-
expect(t).to receive(:
|
404
|
+
expect(t).to receive(:start!)
|
388
405
|
}
|
389
406
|
|
390
407
|
subject.start!
|
@@ -400,7 +417,6 @@ describe Taskinator::Process do
|
|
400
417
|
it "completes when tasks complete" do
|
401
418
|
tasks.each {|t| subject.tasks << t }
|
402
419
|
|
403
|
-
expect(subject).to receive(:can_complete?) { true }
|
404
420
|
expect(subject).to receive(:complete!)
|
405
421
|
|
406
422
|
subject.task_completed(tasks.first)
|
@@ -30,24 +30,6 @@ describe Taskinator::Queues::DelayedJobAdapter, :delayed_job do
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
describe "ProcessWorker" do
|
34
|
-
it "enqueues processes" do
|
35
|
-
expect {
|
36
|
-
subject.enqueue_process(double('process', :uuid => uuid, :queue => nil))
|
37
|
-
}.to change(Delayed::Job.queue, :size).by(1)
|
38
|
-
end
|
39
|
-
|
40
|
-
it "enqueues process to specified queue" do
|
41
|
-
subject.enqueue_process(double('process', :uuid => uuid, :queue => :other))
|
42
|
-
expect(Delayed::Job.contains?(adapter::ProcessWorker, uuid, :other)).to be
|
43
|
-
end
|
44
|
-
|
45
|
-
it "calls process worker" do
|
46
|
-
expect_any_instance_of(Taskinator::ProcessWorker).to receive(:perform)
|
47
|
-
adapter::ProcessWorker.new(uuid).perform
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
33
|
describe "TaskWorker" do
|
52
34
|
it "enqueues tasks" do
|
53
35
|
expect {
|
@@ -92,7 +74,7 @@ describe Taskinator::Queues::DelayedJobAdapter, :delayed_job do
|
|
92
74
|
let(:definition) { TestDefinition }
|
93
75
|
|
94
76
|
it "performs invocation on job" do
|
95
|
-
args = {:a => 1}
|
77
|
+
args = [:foo, {:a => 1}]
|
96
78
|
job = double('job')
|
97
79
|
expect(job).to receive(:perform)
|
98
80
|
|
@@ -34,27 +34,6 @@ describe Taskinator::Queues::ResqueAdapter, :resque do
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
describe "ProcessWorker" do
|
38
|
-
it "enqueues processes" do
|
39
|
-
worker = adapter::ProcessWorker
|
40
|
-
subject.enqueue_process(double('process', :uuid => uuid, :queue => nil))
|
41
|
-
|
42
|
-
expect(worker).to have_queued(uuid)
|
43
|
-
end
|
44
|
-
|
45
|
-
it "enqueues process to specified queue" do
|
46
|
-
worker = adapter::ProcessWorker
|
47
|
-
subject.enqueue_process(double('process', :uuid => uuid, :queue => :other))
|
48
|
-
|
49
|
-
expect(worker).to have_queued(uuid).in(:other)
|
50
|
-
end
|
51
|
-
|
52
|
-
it "calls process worker" do
|
53
|
-
expect_any_instance_of(Taskinator::ProcessWorker).to receive(:perform)
|
54
|
-
adapter::ProcessWorker.perform(uuid)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
37
|
describe "TaskWorker" do
|
59
38
|
it "enqueues tasks" do
|
60
39
|
worker = adapter::TaskWorker
|
@@ -115,7 +94,7 @@ describe Taskinator::Queues::ResqueAdapter, :resque do
|
|
115
94
|
let(:definition) { TestDefinition }
|
116
95
|
|
117
96
|
it "performs invocation on job" do
|
118
|
-
args = {:a => 1}
|
97
|
+
args = [:foo, {:a => 1}]
|
119
98
|
job_class = double('job_class', :methods => [:perform])
|
120
99
|
expect(job_class).to receive(:perform).with(*args)
|
121
100
|
|
@@ -33,25 +33,6 @@ describe Taskinator::Queues::SidekiqAdapter, :sidekiq do
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
describe "ProcessWorker" do
|
37
|
-
it "enqueues processes" do
|
38
|
-
worker = adapter::ProcessWorker
|
39
|
-
process = double('process', :uuid => uuid, :queue => nil)
|
40
|
-
subject.enqueue_process(process)
|
41
|
-
expect(worker).to have_enqueued_job(process.uuid)
|
42
|
-
end
|
43
|
-
|
44
|
-
it "enqueues process to specified queue" do
|
45
|
-
subject.enqueue_process(double('process', :uuid => uuid, :queue => :other))
|
46
|
-
expect(adapter::ProcessWorker).to be_processed_in_x(:other)
|
47
|
-
end
|
48
|
-
|
49
|
-
it "calls process worker" do
|
50
|
-
expect_any_instance_of(Taskinator::ProcessWorker).to receive(:perform)
|
51
|
-
adapter::ProcessWorker.new.perform(uuid)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
36
|
describe "TaskWorker" do
|
56
37
|
it "enqueues tasks" do
|
57
38
|
worker = adapter::TaskWorker
|
@@ -106,7 +87,7 @@ describe Taskinator::Queues::SidekiqAdapter, :sidekiq do
|
|
106
87
|
let(:definition) { TestDefinition }
|
107
88
|
|
108
89
|
it "performs invocation on job" do
|
109
|
-
args = {:a => 1}
|
90
|
+
args = [:foo, {:a => 1}]
|
110
91
|
job = double('job')
|
111
92
|
expect(job).to receive(:perform).with(*args)
|
112
93
|
|
@@ -7,6 +7,7 @@ describe Taskinator::Task do
|
|
7
7
|
describe "Base" do
|
8
8
|
|
9
9
|
let(:process) { Class.new(Taskinator::Process).new(definition) }
|
10
|
+
|
10
11
|
subject { Class.new(Taskinator::Task).new(process) }
|
11
12
|
|
12
13
|
describe "#initialize" do
|
@@ -49,14 +50,6 @@ describe Taskinator::Task do
|
|
49
50
|
it { expect(subject.current_state.name).to eq(:initial) }
|
50
51
|
end
|
51
52
|
|
52
|
-
describe "#can_complete_task?" do
|
53
|
-
it {
|
54
|
-
expect {
|
55
|
-
subject.can_complete_task?
|
56
|
-
}.to raise_error(NotImplementedError)
|
57
|
-
}
|
58
|
-
end
|
59
|
-
|
60
53
|
describe "workflow" do
|
61
54
|
describe "#enqueue!" do
|
62
55
|
it { expect(subject).to respond_to(:enqueue!) }
|
@@ -68,11 +61,6 @@ describe Taskinator::Task do
|
|
68
61
|
subject.enqueue!
|
69
62
|
expect(subject.current_state.name).to eq(:enqueued)
|
70
63
|
}
|
71
|
-
it {
|
72
|
-
expect {
|
73
|
-
subject.enqueue!
|
74
|
-
}.to change { Taskinator.queue.tasks.length }.by(1)
|
75
|
-
}
|
76
64
|
end
|
77
65
|
|
78
66
|
describe "#start!" do
|
@@ -90,9 +78,7 @@ describe Taskinator::Task do
|
|
90
78
|
describe "#complete!" do
|
91
79
|
it { expect(subject).to respond_to(:complete!) }
|
92
80
|
it {
|
93
|
-
expect(subject).to receive(:can_complete_task?) { true }
|
94
81
|
expect(subject).to receive(:complete)
|
95
|
-
expect(process).to receive(:task_completed).with(subject)
|
96
82
|
subject.start!
|
97
83
|
subject.complete!
|
98
84
|
expect(subject.current_state.name).to eq(:completed)
|
@@ -158,10 +144,6 @@ describe Taskinator::Task do
|
|
158
144
|
}
|
159
145
|
end
|
160
146
|
|
161
|
-
describe "#reload" do
|
162
|
-
it { expect(subject.reload).to_not be }
|
163
|
-
end
|
164
|
-
|
165
147
|
describe "#tasks_count" do
|
166
148
|
it {
|
167
149
|
expect(subject.tasks_count).to eq(0)
|
@@ -172,15 +154,15 @@ describe Taskinator::Task do
|
|
172
154
|
describe Taskinator::Task::Step do
|
173
155
|
it_should_behave_like "a task", Taskinator::Task::Step do
|
174
156
|
let(:process) { Class.new(Taskinator::Process).new(definition) }
|
175
|
-
let(:task) { Taskinator::Task.define_step_task(process, :
|
157
|
+
let(:task) { Taskinator::Task.define_step_task(process, :do_task, {:a => 1, :b => 2}) }
|
176
158
|
end
|
177
159
|
|
178
160
|
let(:process) { Class.new(Taskinator::Process).new(definition) }
|
179
|
-
subject { Taskinator::Task.define_step_task(process, :
|
161
|
+
subject { Taskinator::Task.define_step_task(process, :do_task, {:a => 1, :b => 2}) }
|
180
162
|
|
181
163
|
describe ".define_step_task" do
|
182
164
|
it "sets the queue to use" do
|
183
|
-
task = Taskinator::Task.define_step_task(process, :
|
165
|
+
task = Taskinator::Task.define_step_task(process, :do_task, {:a => 1, :b => 2}, :queue => :foo)
|
184
166
|
expect(task.queue).to eq(:foo)
|
185
167
|
end
|
186
168
|
end
|
@@ -188,18 +170,47 @@ describe Taskinator::Task do
|
|
188
170
|
describe "#executor" do
|
189
171
|
it { expect(subject.executor).to_not be_nil }
|
190
172
|
it { expect(subject.executor).to be_a(definition) }
|
191
|
-
end
|
192
|
-
|
193
|
-
describe "#start!" do
|
194
|
-
it "invokes executor" do
|
195
|
-
expect(subject.executor).to receive(subject.method).with(*subject.args)
|
196
|
-
subject.start!
|
197
|
-
end
|
198
173
|
|
199
174
|
it "handles failure" do
|
200
175
|
error = StandardError.new
|
201
176
|
allow(subject.executor).to receive(subject.method).with(*subject.args).and_raise(error)
|
202
177
|
expect(subject).to receive(:fail!).with(error)
|
178
|
+
expect {
|
179
|
+
subject.start!
|
180
|
+
}.to raise_error(error)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe "#enqueue!" do
|
185
|
+
it {
|
186
|
+
expect {
|
187
|
+
subject.enqueue!
|
188
|
+
}.to change { Taskinator.queue.tasks.length }.by(1)
|
189
|
+
}
|
190
|
+
|
191
|
+
it "is instrumented" do
|
192
|
+
allow(subject.executor).to receive(subject.method).with(*subject.args)
|
193
|
+
|
194
|
+
instrumentation_block = SpecSupport::Block.new
|
195
|
+
|
196
|
+
expect(instrumentation_block).to receive(:call) do |*args|
|
197
|
+
expect(args.first).to eq('taskinator.task.enqueued')
|
198
|
+
end
|
199
|
+
|
200
|
+
# temporary subscription
|
201
|
+
ActiveSupport::Notifications.subscribed(instrumentation_block, /taskinator.task/) do
|
202
|
+
subject.enqueue!
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
describe "#start!" do
|
208
|
+
before do
|
209
|
+
expect(process).to receive(:task_completed).with(subject)
|
210
|
+
end
|
211
|
+
|
212
|
+
it "invokes executor" do
|
213
|
+
expect(subject.executor).to receive(subject.method).with(*subject.args)
|
203
214
|
subject.start!
|
204
215
|
end
|
205
216
|
|
@@ -232,25 +243,39 @@ describe Taskinator::Task do
|
|
232
243
|
end
|
233
244
|
|
234
245
|
it "is instrumented" do
|
235
|
-
allow(subject.executor).to receive(subject.method)
|
236
|
-
|
237
246
|
instrumentation_block = SpecSupport::Block.new
|
238
|
-
|
247
|
+
|
248
|
+
expect(instrumentation_block).to receive(:call) do |*args|
|
249
|
+
expect(args.first).to eq('taskinator.task.started')
|
250
|
+
end
|
251
|
+
|
252
|
+
# special case, since when the method returns, the task is considered to be complete
|
253
|
+
expect(instrumentation_block).to receive(:call) do |*args|
|
254
|
+
expect(args.first).to eq('taskinator.task.completed')
|
255
|
+
end
|
239
256
|
|
240
257
|
# temporary subscription
|
241
|
-
ActiveSupport::Notifications.subscribed(instrumentation_block, /
|
258
|
+
ActiveSupport::Notifications.subscribed(instrumentation_block, /taskinator.task/) do
|
242
259
|
subject.start!
|
243
260
|
end
|
244
261
|
end
|
245
262
|
end
|
246
263
|
|
247
|
-
describe "#
|
248
|
-
it
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
264
|
+
describe "#complete" do
|
265
|
+
it "is instrumented" do
|
266
|
+
allow(process).to receive(:task_completed)
|
267
|
+
|
268
|
+
instrumentation_block = SpecSupport::Block.new
|
269
|
+
|
270
|
+
expect(instrumentation_block).to receive(:call) do |*args|
|
271
|
+
expect(args.first).to eq('taskinator.task.completed')
|
272
|
+
end
|
273
|
+
|
274
|
+
# temporary subscription
|
275
|
+
ActiveSupport::Notifications.subscribed(instrumentation_block, /taskinator.task/) do
|
276
|
+
subject.complete!
|
277
|
+
end
|
278
|
+
end
|
254
279
|
end
|
255
280
|
|
256
281
|
describe "#accept" do
|
@@ -307,9 +332,26 @@ describe Taskinator::Task do
|
|
307
332
|
subject.enqueue!
|
308
333
|
}.to change { Taskinator.queue.jobs.length }.by(1)
|
309
334
|
}
|
335
|
+
|
336
|
+
it "is instrumented" do
|
337
|
+
instrumentation_block = SpecSupport::Block.new
|
338
|
+
|
339
|
+
expect(instrumentation_block).to receive(:call) do |*args|
|
340
|
+
expect(args.first).to eq('taskinator.task.enqueued')
|
341
|
+
end
|
342
|
+
|
343
|
+
# temporary subscription
|
344
|
+
ActiveSupport::Notifications.subscribed(instrumentation_block, /taskinator.task/) do
|
345
|
+
subject.enqueue!
|
346
|
+
end
|
347
|
+
end
|
310
348
|
end
|
311
349
|
|
312
350
|
describe "#perform" do
|
351
|
+
before do
|
352
|
+
expect(process).to receive(:task_completed).with(subject)
|
353
|
+
end
|
354
|
+
|
313
355
|
it {
|
314
356
|
block = SpecSupport::Block.new
|
315
357
|
expect(block).to receive(:call).with(TestJob, {:a => 1, :b => 2})
|
@@ -319,18 +361,43 @@ describe Taskinator::Task do
|
|
319
361
|
|
320
362
|
it "is instrumented" do
|
321
363
|
block = SpecSupport::Block.new
|
322
|
-
allow(block).to receive(:call)
|
364
|
+
allow(block).to receive(:call).with(TestJob, {:a => 1, :b => 2})
|
323
365
|
|
324
366
|
instrumentation_block = SpecSupport::Block.new
|
325
|
-
|
367
|
+
|
368
|
+
expect(instrumentation_block).to receive(:call) do |*args|
|
369
|
+
expect(args.first).to eq('taskinator.task.started')
|
370
|
+
end
|
371
|
+
|
372
|
+
# special case, since when the method returns, the task is considered to be complete
|
373
|
+
expect(instrumentation_block).to receive(:call) do |*args|
|
374
|
+
expect(args.first).to eq('taskinator.task.completed')
|
375
|
+
end
|
326
376
|
|
327
377
|
# temporary subscription
|
328
|
-
ActiveSupport::Notifications.subscribed(instrumentation_block, /
|
378
|
+
ActiveSupport::Notifications.subscribed(instrumentation_block, /taskinator.task/) do
|
329
379
|
subject.perform(&block)
|
330
380
|
end
|
331
381
|
end
|
332
382
|
end
|
333
383
|
|
384
|
+
describe "#complete" do
|
385
|
+
it "is instrumented" do
|
386
|
+
allow(process).to receive(:task_completed)
|
387
|
+
|
388
|
+
instrumentation_block = SpecSupport::Block.new
|
389
|
+
|
390
|
+
expect(instrumentation_block).to receive(:call) do |*args|
|
391
|
+
expect(args.first).to eq('taskinator.task.completed')
|
392
|
+
end
|
393
|
+
|
394
|
+
# temporary subscription
|
395
|
+
ActiveSupport::Notifications.subscribed(instrumentation_block, /taskinator.task/) do
|
396
|
+
subject.complete!
|
397
|
+
end
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
334
401
|
describe "#accept" do
|
335
402
|
it {
|
336
403
|
expect(subject).to receive(:accept)
|
@@ -375,6 +442,34 @@ describe Taskinator::Task do
|
|
375
442
|
end
|
376
443
|
end
|
377
444
|
|
445
|
+
describe "#enqueue!" do
|
446
|
+
context "without tasks" do
|
447
|
+
it {
|
448
|
+
expect {
|
449
|
+
subject.enqueue!
|
450
|
+
}.to change { Taskinator.queue.tasks.length }.by(0)
|
451
|
+
}
|
452
|
+
end
|
453
|
+
|
454
|
+
it "delegates to sub process" do
|
455
|
+
expect(sub_process).to receive(:enqueue!)
|
456
|
+
subject.enqueue!
|
457
|
+
end
|
458
|
+
|
459
|
+
it "is instrumented" do
|
460
|
+
instrumentation_block = SpecSupport::Block.new
|
461
|
+
|
462
|
+
expect(instrumentation_block).to receive(:call) do |*args|
|
463
|
+
expect(args.first).to eq('taskinator.task.enqueued')
|
464
|
+
end
|
465
|
+
|
466
|
+
# temporary subscription
|
467
|
+
ActiveSupport::Notifications.subscribed(instrumentation_block, /taskinator.task/) do
|
468
|
+
subject.enqueue!
|
469
|
+
end
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
378
473
|
describe "#start!" do
|
379
474
|
it "delegates to sub process" do
|
380
475
|
expect(sub_process).to receive(:start)
|
@@ -385,26 +480,39 @@ describe Taskinator::Task do
|
|
385
480
|
error = StandardError.new
|
386
481
|
allow(sub_process).to receive(:start!).and_raise(error)
|
387
482
|
expect(subject).to receive(:fail!).with(error)
|
388
|
-
|
483
|
+
expect {
|
484
|
+
subject.start!
|
485
|
+
}.to raise_error(error)
|
389
486
|
end
|
390
487
|
|
391
488
|
it "is instrumented" do
|
392
|
-
allow(sub_process).to receive(:start)
|
393
|
-
|
394
489
|
instrumentation_block = SpecSupport::Block.new
|
395
|
-
|
490
|
+
|
491
|
+
expect(instrumentation_block).to receive(:call) do |*args|
|
492
|
+
expect(args.first).to eq('taskinator.task.started')
|
493
|
+
end
|
396
494
|
|
397
495
|
# temporary subscription
|
398
|
-
ActiveSupport::Notifications.subscribed(instrumentation_block, /
|
496
|
+
ActiveSupport::Notifications.subscribed(instrumentation_block, /taskinator.task/) do
|
399
497
|
subject.start!
|
400
498
|
end
|
401
499
|
end
|
402
500
|
end
|
403
501
|
|
404
|
-
describe "#
|
405
|
-
it "
|
406
|
-
|
407
|
-
|
502
|
+
describe "#complete" do
|
503
|
+
it "is instrumented" do
|
504
|
+
allow(process).to receive(:task_completed)
|
505
|
+
|
506
|
+
instrumentation_block = SpecSupport::Block.new
|
507
|
+
|
508
|
+
expect(instrumentation_block).to receive(:call) do |*args|
|
509
|
+
expect(args.first).to eq('taskinator.task.completed')
|
510
|
+
end
|
511
|
+
|
512
|
+
# temporary subscription
|
513
|
+
ActiveSupport::Notifications.subscribed(instrumentation_block, /taskinator.task/) do
|
514
|
+
subject.complete!
|
515
|
+
end
|
408
516
|
end
|
409
517
|
end
|
410
518
|
|
@@ -24,22 +24,6 @@ describe Taskinator::TaskWorker do
|
|
24
24
|
subject.perform
|
25
25
|
end
|
26
26
|
|
27
|
-
it "should complete the task if can_complete? is true" do
|
28
|
-
task = mock_task(false, false, true)
|
29
|
-
allow(Taskinator::Task).to receive(:fetch).with(uuid) { task }
|
30
|
-
allow(task).to receive(:start!)
|
31
|
-
expect(task).to receive(:complete!)
|
32
|
-
subject.perform
|
33
|
-
end
|
34
|
-
|
35
|
-
it "should not complete the task if can_complete? is false" do
|
36
|
-
task = mock_task
|
37
|
-
allow(Taskinator::Task).to receive(:fetch).with(uuid) { task }
|
38
|
-
allow(task).to receive(:start!)
|
39
|
-
expect(task).to_not receive(:complete!)
|
40
|
-
subject.perform
|
41
|
-
end
|
42
|
-
|
43
27
|
it "should not start if paused" do
|
44
28
|
task = mock_task(true, false)
|
45
29
|
allow(Taskinator::Task).to receive(:fetch).with(uuid) { task }
|
@@ -58,7 +42,6 @@ describe Taskinator::TaskWorker do
|
|
58
42
|
task = mock_task
|
59
43
|
allow(Taskinator::Task).to receive(:fetch).with(uuid) { task }
|
60
44
|
allow(task).to receive(:start!) { raise StandardError }
|
61
|
-
expect(task).to receive(:fail!).with(StandardError)
|
62
45
|
expect {
|
63
46
|
subject.perform
|
64
47
|
}.to raise_error(StandardError)
|
@@ -85,4 +85,47 @@ describe TestFlows do
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
end
|
88
|
+
|
89
|
+
describe "scenarios" do
|
90
|
+
|
91
|
+
before do
|
92
|
+
# use the "synchronous" queue
|
93
|
+
Taskinator.queue_adapter = :test_queue_worker
|
94
|
+
end
|
95
|
+
|
96
|
+
context "empty subprocesses" do
|
97
|
+
|
98
|
+
context "sequential" do
|
99
|
+
let(:definition) { TestFlows::EmptySequentialProcessTest }
|
100
|
+
subject { definition.create_process }
|
101
|
+
|
102
|
+
it "invokes each task" do
|
103
|
+
# this doesn't work...
|
104
|
+
# expect_any_instance_of(Taskinator::Executor).to receive(:do_task_x).exactly(3).times
|
105
|
+
# subject.start!
|
106
|
+
|
107
|
+
expect {
|
108
|
+
subject.enqueue!
|
109
|
+
}.to change { Taskinator.queue.tasks.length }.by(3)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context "concurrent" do
|
114
|
+
let(:definition) { TestFlows::EmptyConcurrentProcessTest }
|
115
|
+
subject { definition.create_process }
|
116
|
+
|
117
|
+
it "invokes each task" do
|
118
|
+
# this doesn't work...
|
119
|
+
# expect_any_instance_of(Taskinator::Executor).to receive(:do_task_x).exactly(3).times
|
120
|
+
# subject.start!
|
121
|
+
|
122
|
+
expect {
|
123
|
+
subject.enqueue!
|
124
|
+
}.to change { Taskinator.queue.tasks.length }.by(3)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
88
131
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: taskinator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Stefano
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-07-
|
11
|
+
date: 2015-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -268,7 +268,6 @@ files:
|
|
268
268
|
- lib/taskinator/logger.rb
|
269
269
|
- lib/taskinator/persistence.rb
|
270
270
|
- lib/taskinator/process.rb
|
271
|
-
- lib/taskinator/process_worker.rb
|
272
271
|
- lib/taskinator/queues.rb
|
273
272
|
- lib/taskinator/queues/delayed_job.rb
|
274
273
|
- lib/taskinator/queues/resque.rb
|
@@ -305,7 +304,6 @@ files:
|
|
305
304
|
- spec/taskinator/job_worker_spec.rb
|
306
305
|
- spec/taskinator/persistence_spec.rb
|
307
306
|
- spec/taskinator/process_spec.rb
|
308
|
-
- spec/taskinator/process_worker_spec.rb
|
309
307
|
- spec/taskinator/queues/delayed_job_spec.rb
|
310
308
|
- spec/taskinator/queues/resque_spec.rb
|
311
309
|
- spec/taskinator/queues/sidekiq_spec.rb
|
@@ -368,7 +366,6 @@ test_files:
|
|
368
366
|
- spec/taskinator/job_worker_spec.rb
|
369
367
|
- spec/taskinator/persistence_spec.rb
|
370
368
|
- spec/taskinator/process_spec.rb
|
371
|
-
- spec/taskinator/process_worker_spec.rb
|
372
369
|
- spec/taskinator/queues/delayed_job_spec.rb
|
373
370
|
- spec/taskinator/queues/resque_spec.rb
|
374
371
|
- spec/taskinator/queues/sidekiq_spec.rb
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module Taskinator
|
2
|
-
class ProcessWorker
|
3
|
-
attr_reader :uuid
|
4
|
-
|
5
|
-
def initialize(uuid)
|
6
|
-
@uuid = uuid
|
7
|
-
end
|
8
|
-
|
9
|
-
def perform
|
10
|
-
process = Taskinator::Process.fetch(@uuid)
|
11
|
-
return if process.paused? || process.cancelled?
|
12
|
-
begin
|
13
|
-
process.start!
|
14
|
-
rescue => e
|
15
|
-
Taskinator.logger.error(e)
|
16
|
-
process.fail!(e)
|
17
|
-
raise e
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|