taskinator 0.2.0 → 0.3.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 +10 -0
- data/Gemfile +17 -2
- data/Gemfile.lock +57 -18
- data/README.md +20 -16
- data/lib/taskinator/definition.rb +2 -2
- data/lib/taskinator/instrumentation.rb +77 -0
- data/lib/taskinator/persistence.rb +72 -61
- data/lib/taskinator/process.rb +118 -99
- data/lib/taskinator/queues/delayed_job.rb +0 -14
- data/lib/taskinator/queues/resque.rb +0 -18
- data/lib/taskinator/queues/sidekiq.rb +0 -14
- data/lib/taskinator/queues.rb +0 -5
- data/lib/taskinator/task.rb +113 -70
- data/lib/taskinator/version.rb +1 -1
- data/lib/taskinator/visitor.rb +6 -0
- data/lib/taskinator/workflow.rb +36 -0
- data/lib/taskinator.rb +3 -2
- data/spec/examples/process_examples.rb +6 -9
- data/spec/examples/queue_adapter_examples.rb +2 -12
- data/spec/examples/task_examples.rb +5 -8
- data/spec/support/process_methods.rb +25 -0
- data/spec/support/task_methods.rb +13 -0
- data/spec/support/test_flows.rb +1 -3
- data/spec/support/test_instrumenter.rb +39 -0
- data/spec/support/test_queue.rb +0 -12
- data/spec/taskinator/definition_spec.rb +3 -5
- data/spec/taskinator/instrumentation_spec.rb +98 -0
- data/spec/taskinator/persistence_spec.rb +3 -41
- data/spec/taskinator/process_spec.rb +36 -34
- data/spec/taskinator/queues/delayed_job_spec.rb +0 -41
- data/spec/taskinator/queues/resque_spec.rb +0 -51
- data/spec/taskinator/queues/sidekiq_spec.rb +0 -50
- data/spec/taskinator/queues_spec.rb +1 -1
- data/spec/taskinator/task_spec.rb +96 -64
- data/spec/taskinator/test_flows_spec.rb +266 -1
- data/taskinator.gemspec +0 -21
- metadata +12 -173
- data/lib/taskinator/job_worker.rb +0 -17
- data/spec/taskinator/job_worker_spec.rb +0 -62
@@ -4,11 +4,19 @@ describe Taskinator::Task do
|
|
4
4
|
|
5
5
|
let(:definition) { TestDefinition }
|
6
6
|
|
7
|
-
|
7
|
+
let(:process) do
|
8
|
+
Class.new(Taskinator::Process) do
|
9
|
+
include ProcessMethods
|
10
|
+
end.new(definition)
|
11
|
+
end
|
8
12
|
|
9
|
-
|
13
|
+
describe "Base" do
|
10
14
|
|
11
|
-
subject
|
15
|
+
subject do
|
16
|
+
Class.new(Taskinator::Task) do
|
17
|
+
include TaskMethods
|
18
|
+
end.new(process)
|
19
|
+
end
|
12
20
|
|
13
21
|
describe "#initialize" do
|
14
22
|
it { expect(subject.process).to_not be_nil }
|
@@ -45,9 +53,9 @@ describe Taskinator::Task do
|
|
45
53
|
end
|
46
54
|
|
47
55
|
describe "#current_state" do
|
48
|
-
it { expect(subject).to be_a(::Workflow) }
|
56
|
+
it { expect(subject).to be_a(Taskinator::Workflow) }
|
49
57
|
it { expect(subject.current_state).to_not be_nil }
|
50
|
-
it { expect(subject.current_state
|
58
|
+
it { expect(subject.current_state).to eq(:initial) }
|
51
59
|
end
|
52
60
|
|
53
61
|
describe "workflow" do
|
@@ -59,7 +67,7 @@ describe Taskinator::Task do
|
|
59
67
|
}
|
60
68
|
it {
|
61
69
|
subject.enqueue!
|
62
|
-
expect(subject.current_state
|
70
|
+
expect(subject.current_state).to eq(:enqueued)
|
63
71
|
}
|
64
72
|
end
|
65
73
|
|
@@ -71,7 +79,7 @@ describe Taskinator::Task do
|
|
71
79
|
}
|
72
80
|
it {
|
73
81
|
subject.start!
|
74
|
-
expect(subject.current_state
|
82
|
+
expect(subject.current_state).to eq(:processing)
|
75
83
|
}
|
76
84
|
end
|
77
85
|
|
@@ -81,7 +89,7 @@ describe Taskinator::Task do
|
|
81
89
|
expect(subject).to receive(:complete)
|
82
90
|
subject.start!
|
83
91
|
subject.complete!
|
84
|
-
expect(subject.current_state
|
92
|
+
expect(subject.current_state).to eq(:completed)
|
85
93
|
}
|
86
94
|
end
|
87
95
|
|
@@ -96,8 +104,8 @@ describe Taskinator::Task do
|
|
96
104
|
}
|
97
105
|
it {
|
98
106
|
subject.start!
|
99
|
-
subject.fail!
|
100
|
-
expect(subject.current_state
|
107
|
+
subject.fail!(StandardError.new)
|
108
|
+
expect(subject.current_state).to eq(:failed)
|
101
109
|
}
|
102
110
|
end
|
103
111
|
|
@@ -106,7 +114,7 @@ describe Taskinator::Task do
|
|
106
114
|
it {
|
107
115
|
process.start!
|
108
116
|
process.pause!
|
109
|
-
expect(subject.paused?).to
|
117
|
+
expect(subject.paused?).to eq(true)
|
110
118
|
}
|
111
119
|
end
|
112
120
|
|
@@ -139,6 +147,8 @@ describe Taskinator::Task do
|
|
139
147
|
expect(visitor).to receive(:visit_task_reference).with(:next)
|
140
148
|
expect(visitor).to receive(:visit_args).with(:options)
|
141
149
|
expect(visitor).to receive(:visit_attribute).with(:queue)
|
150
|
+
expect(visitor).to receive(:visit_attribute_time).with(:created_at)
|
151
|
+
expect(visitor).to receive(:visit_attribute_time).with(:updated_at)
|
142
152
|
|
143
153
|
subject.accept(visitor)
|
144
154
|
}
|
@@ -152,14 +162,11 @@ describe Taskinator::Task do
|
|
152
162
|
end
|
153
163
|
|
154
164
|
describe Taskinator::Task::Step do
|
155
|
-
it_should_behave_like "a task", Taskinator::Task::Step do
|
156
|
-
let(:process) { Class.new(Taskinator::Process).new(definition) }
|
157
|
-
let(:task) { Taskinator::Task.define_step_task(process, :do_task, {:a => 1, :b => 2}) }
|
158
|
-
end
|
159
165
|
|
160
|
-
let(:process) { Class.new(Taskinator::Process).new(definition) }
|
161
166
|
subject { Taskinator::Task.define_step_task(process, :do_task, {:a => 1, :b => 2}) }
|
162
167
|
|
168
|
+
it_should_behave_like "a task", Taskinator::Task::Step
|
169
|
+
|
163
170
|
describe ".define_step_task" do
|
164
171
|
it "sets the queue to use" do
|
165
172
|
task = Taskinator::Task.define_step_task(process, :do_task, {:a => 1, :b => 2}, :queue => :foo)
|
@@ -197,8 +204,7 @@ describe Taskinator::Task do
|
|
197
204
|
expect(args.first).to eq('taskinator.task.enqueued')
|
198
205
|
end
|
199
206
|
|
200
|
-
|
201
|
-
ActiveSupport::Notifications.subscribed(instrumentation_block, /taskinator.task/) do
|
207
|
+
TestInstrumenter.subscribe(instrumentation_block, /taskinator.task/) do
|
202
208
|
subject.enqueue!
|
203
209
|
end
|
204
210
|
end
|
@@ -206,7 +212,7 @@ describe Taskinator::Task do
|
|
206
212
|
|
207
213
|
describe "#start!" do
|
208
214
|
before do
|
209
|
-
|
215
|
+
allow(process).to receive(:task_completed).with(subject)
|
210
216
|
end
|
211
217
|
|
212
218
|
it "invokes executor" do
|
@@ -246,24 +252,28 @@ describe Taskinator::Task do
|
|
246
252
|
instrumentation_block = SpecSupport::Block.new
|
247
253
|
|
248
254
|
expect(instrumentation_block).to receive(:call) do |*args|
|
249
|
-
expect(args.first).to eq('taskinator.task.
|
255
|
+
expect(args.first).to eq('taskinator.task.processing')
|
250
256
|
end
|
251
257
|
|
252
|
-
# special case, since when the method returns, the task is considered to be complete
|
253
258
|
expect(instrumentation_block).to receive(:call) do |*args|
|
254
259
|
expect(args.first).to eq('taskinator.task.completed')
|
255
260
|
end
|
256
261
|
|
257
|
-
|
258
|
-
ActiveSupport::Notifications.subscribed(instrumentation_block, /taskinator.task/) do
|
262
|
+
TestInstrumenter.subscribe(instrumentation_block) do
|
259
263
|
subject.start!
|
260
264
|
end
|
261
265
|
end
|
262
266
|
end
|
263
267
|
|
264
268
|
describe "#complete" do
|
269
|
+
it "notifies parent process" do
|
270
|
+
expect(process).to receive(:task_completed).with(subject)
|
271
|
+
|
272
|
+
subject.complete!
|
273
|
+
end
|
274
|
+
|
265
275
|
it "is instrumented" do
|
266
|
-
allow(process).to receive(:task_completed)
|
276
|
+
allow(process).to receive(:task_completed).with(subject)
|
267
277
|
|
268
278
|
instrumentation_block = SpecSupport::Block.new
|
269
279
|
|
@@ -271,8 +281,7 @@ describe Taskinator::Task do
|
|
271
281
|
expect(args.first).to eq('taskinator.task.completed')
|
272
282
|
end
|
273
283
|
|
274
|
-
|
275
|
-
ActiveSupport::Notifications.subscribed(instrumentation_block, /taskinator.task/) do
|
284
|
+
TestInstrumenter.subscribe(instrumentation_block, /taskinator.task/) do
|
276
285
|
subject.complete!
|
277
286
|
end
|
278
287
|
end
|
@@ -294,6 +303,8 @@ describe Taskinator::Task do
|
|
294
303
|
expect(visitor).to receive(:visit_attribute).with(:method)
|
295
304
|
expect(visitor).to receive(:visit_args).with(:args)
|
296
305
|
expect(visitor).to receive(:visit_attribute).with(:queue)
|
306
|
+
expect(visitor).to receive(:visit_attribute_time).with(:created_at)
|
307
|
+
expect(visitor).to receive(:visit_attribute_time).with(:updated_at)
|
297
308
|
|
298
309
|
subject.accept(visitor)
|
299
310
|
}
|
@@ -311,14 +322,20 @@ describe Taskinator::Task do
|
|
311
322
|
end
|
312
323
|
end
|
313
324
|
|
314
|
-
|
315
|
-
|
316
|
-
|
325
|
+
class TestJobClass
|
326
|
+
def perform(*args)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
module TestJobModule
|
331
|
+
def self.perform(*args)
|
332
|
+
end
|
317
333
|
end
|
318
334
|
|
319
|
-
let(:process) { Class.new(Taskinator::Process).new(definition) }
|
320
335
|
subject { Taskinator::Task.define_job_task(process, TestJob, {:a => 1, :b => 2}) }
|
321
336
|
|
337
|
+
it_should_behave_like "a task", Taskinator::Task::Job
|
338
|
+
|
322
339
|
describe ".define_job_task" do
|
323
340
|
it "sets the queue to use" do
|
324
341
|
task = Taskinator::Task.define_job_task(process, TestJob, {:a => 1, :b => 2}, :queue => :foo)
|
@@ -330,7 +347,7 @@ describe Taskinator::Task do
|
|
330
347
|
it {
|
331
348
|
expect {
|
332
349
|
subject.enqueue!
|
333
|
-
}.to change { Taskinator.queue.
|
350
|
+
}.to change { Taskinator.queue.tasks.length }.by(1)
|
334
351
|
}
|
335
352
|
|
336
353
|
it "is instrumented" do
|
@@ -340,33 +357,36 @@ describe Taskinator::Task do
|
|
340
357
|
expect(args.first).to eq('taskinator.task.enqueued')
|
341
358
|
end
|
342
359
|
|
343
|
-
|
344
|
-
ActiveSupport::Notifications.subscribed(instrumentation_block, /taskinator.task/) do
|
360
|
+
TestInstrumenter.subscribe(instrumentation_block, /taskinator.task/) do
|
345
361
|
subject.enqueue!
|
346
362
|
end
|
347
363
|
end
|
348
364
|
end
|
349
365
|
|
350
|
-
describe "#
|
351
|
-
before do
|
352
|
-
expect(process).to receive(:task_completed).with(subject)
|
353
|
-
end
|
354
|
-
|
366
|
+
describe "#start" do
|
355
367
|
it {
|
356
|
-
|
357
|
-
expect(
|
368
|
+
task = Taskinator::Task.define_job_task(process, TestJobClass, {:a => 1, :b => 2})
|
369
|
+
expect(process).to receive(:task_completed).with(task)
|
370
|
+
expect_any_instance_of(TestJobClass).to receive(:perform).with({:a => 1, :b => 2})
|
371
|
+
task.start!
|
372
|
+
}
|
358
373
|
|
359
|
-
|
374
|
+
it {
|
375
|
+
task = Taskinator::Task.define_job_task(process, TestJobModule, {:a => 1, :b => 2})
|
376
|
+
expect(process).to receive(:task_completed).with(task)
|
377
|
+
expect(TestJobModule).to receive(:perform).with({:a => 1, :b => 2})
|
378
|
+
task.start!
|
360
379
|
}
|
361
380
|
|
362
381
|
it "is instrumented" do
|
363
|
-
|
364
|
-
|
382
|
+
allow(process).to receive(:task_completed).with(subject)
|
383
|
+
|
384
|
+
allow(TestJob).to receive(:perform).with({:a => 1, :b => 2})
|
365
385
|
|
366
386
|
instrumentation_block = SpecSupport::Block.new
|
367
387
|
|
368
388
|
expect(instrumentation_block).to receive(:call) do |*args|
|
369
|
-
expect(args.first).to eq('taskinator.task.
|
389
|
+
expect(args.first).to eq('taskinator.task.processing')
|
370
390
|
end
|
371
391
|
|
372
392
|
# special case, since when the method returns, the task is considered to be complete
|
@@ -374,16 +394,21 @@ describe Taskinator::Task do
|
|
374
394
|
expect(args.first).to eq('taskinator.task.completed')
|
375
395
|
end
|
376
396
|
|
377
|
-
|
378
|
-
|
379
|
-
subject.perform(&block)
|
397
|
+
TestInstrumenter.subscribe(instrumentation_block, /taskinator.task/) do
|
398
|
+
subject.start!
|
380
399
|
end
|
381
400
|
end
|
382
401
|
end
|
383
402
|
|
384
403
|
describe "#complete" do
|
404
|
+
it "notifies parent process" do
|
405
|
+
expect(process).to receive(:task_completed).with(subject)
|
406
|
+
|
407
|
+
subject.complete!
|
408
|
+
end
|
409
|
+
|
385
410
|
it "is instrumented" do
|
386
|
-
allow(process).to receive(:task_completed)
|
411
|
+
allow(process).to receive(:task_completed).with(subject)
|
387
412
|
|
388
413
|
instrumentation_block = SpecSupport::Block.new
|
389
414
|
|
@@ -391,8 +416,7 @@ describe Taskinator::Task do
|
|
391
416
|
expect(args.first).to eq('taskinator.task.completed')
|
392
417
|
end
|
393
418
|
|
394
|
-
|
395
|
-
ActiveSupport::Notifications.subscribed(instrumentation_block, /taskinator.task/) do
|
419
|
+
TestInstrumenter.subscribe(instrumentation_block, /taskinator.task/) do
|
396
420
|
subject.complete!
|
397
421
|
end
|
398
422
|
end
|
@@ -414,6 +438,8 @@ describe Taskinator::Task do
|
|
414
438
|
expect(visitor).to receive(:visit_type).with(:job)
|
415
439
|
expect(visitor).to receive(:visit_args).with(:args)
|
416
440
|
expect(visitor).to receive(:visit_attribute).with(:queue)
|
441
|
+
expect(visitor).to receive(:visit_attribute_time).with(:created_at)
|
442
|
+
expect(visitor).to receive(:visit_attribute_time).with(:updated_at)
|
417
443
|
|
418
444
|
subject.accept(visitor)
|
419
445
|
}
|
@@ -425,16 +451,17 @@ describe Taskinator::Task do
|
|
425
451
|
end
|
426
452
|
|
427
453
|
describe Taskinator::Task::SubProcess do
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
454
|
+
|
455
|
+
let(:sub_process) do
|
456
|
+
Class.new(Taskinator::Process) do
|
457
|
+
include ProcessMethods
|
458
|
+
end.new(definition)
|
432
459
|
end
|
433
460
|
|
434
|
-
let(:process) { Class.new(Taskinator::Process).new(definition) }
|
435
|
-
let(:sub_process) { Class.new(Taskinator::Process).new(definition) }
|
436
461
|
subject { Taskinator::Task.define_sub_process_task(process, sub_process) }
|
437
462
|
|
463
|
+
it_should_behave_like "a task", Taskinator::Task::SubProcess
|
464
|
+
|
438
465
|
describe ".define_sub_process_task" do
|
439
466
|
it "sets the queue to use" do
|
440
467
|
task = Taskinator::Task.define_sub_process_task(process, sub_process, :queue => :foo)
|
@@ -463,8 +490,7 @@ describe Taskinator::Task do
|
|
463
490
|
expect(args.first).to eq('taskinator.task.enqueued')
|
464
491
|
end
|
465
492
|
|
466
|
-
|
467
|
-
ActiveSupport::Notifications.subscribed(instrumentation_block, /taskinator.task/) do
|
493
|
+
TestInstrumenter.subscribe(instrumentation_block, /taskinator.task/) do
|
468
494
|
subject.enqueue!
|
469
495
|
end
|
470
496
|
end
|
@@ -489,19 +515,24 @@ describe Taskinator::Task do
|
|
489
515
|
instrumentation_block = SpecSupport::Block.new
|
490
516
|
|
491
517
|
expect(instrumentation_block).to receive(:call) do |*args|
|
492
|
-
expect(args.first).to eq('taskinator.task.
|
518
|
+
expect(args.first).to eq('taskinator.task.processing')
|
493
519
|
end
|
494
520
|
|
495
|
-
|
496
|
-
ActiveSupport::Notifications.subscribed(instrumentation_block, /taskinator.task/) do
|
521
|
+
TestInstrumenter.subscribe(instrumentation_block, /taskinator.task/) do
|
497
522
|
subject.start!
|
498
523
|
end
|
499
524
|
end
|
500
525
|
end
|
501
526
|
|
502
527
|
describe "#complete" do
|
528
|
+
it "notifies parent process" do
|
529
|
+
expect(process).to receive(:task_completed).with(subject)
|
530
|
+
|
531
|
+
subject.complete!
|
532
|
+
end
|
533
|
+
|
503
534
|
it "is instrumented" do
|
504
|
-
allow(process).to receive(:task_completed)
|
535
|
+
allow(process).to receive(:task_completed).with(subject)
|
505
536
|
|
506
537
|
instrumentation_block = SpecSupport::Block.new
|
507
538
|
|
@@ -509,8 +540,7 @@ describe Taskinator::Task do
|
|
509
540
|
expect(args.first).to eq('taskinator.task.completed')
|
510
541
|
end
|
511
542
|
|
512
|
-
|
513
|
-
ActiveSupport::Notifications.subscribed(instrumentation_block, /taskinator.task/) do
|
543
|
+
TestInstrumenter.subscribe(instrumentation_block, /taskinator.task/) do
|
514
544
|
subject.complete!
|
515
545
|
end
|
516
546
|
end
|
@@ -530,6 +560,8 @@ describe Taskinator::Task do
|
|
530
560
|
expect(visitor).to receive(:visit_args).with(:options)
|
531
561
|
expect(visitor).to receive(:visit_process).with(:sub_process)
|
532
562
|
expect(visitor).to receive(:visit_attribute).with(:queue)
|
563
|
+
expect(visitor).to receive(:visit_attribute_time).with(:created_at)
|
564
|
+
expect(visitor).to receive(:visit_attribute_time).with(:updated_at)
|
533
565
|
|
534
566
|
subject.accept(visitor)
|
535
567
|
}
|
@@ -6,7 +6,6 @@ describe TestFlows do
|
|
6
6
|
TestFlows::Task,
|
7
7
|
TestFlows::Job,
|
8
8
|
TestFlows::SubProcess,
|
9
|
-
TestFlows::Sequential,
|
10
9
|
TestFlows::Sequential
|
11
10
|
].each do |definition|
|
12
11
|
|
@@ -128,4 +127,270 @@ describe TestFlows do
|
|
128
127
|
end
|
129
128
|
end
|
130
129
|
|
130
|
+
describe "statuses" do
|
131
|
+
describe "task" do
|
132
|
+
before do
|
133
|
+
# override enqueue
|
134
|
+
allow_any_instance_of(Taskinator::Task::Step).to receive(:enqueue!) { |task|
|
135
|
+
# emulate the worker starting the task
|
136
|
+
task.start!
|
137
|
+
}
|
138
|
+
end
|
139
|
+
|
140
|
+
let(:task_count) { 2 }
|
141
|
+
let(:definition) { TestFlows::Task }
|
142
|
+
subject { definition.create_process(task_count) }
|
143
|
+
|
144
|
+
it "reports process and task state" do
|
145
|
+
|
146
|
+
instrumenter = TestInstrumenter.new do |name, payload|
|
147
|
+
|
148
|
+
case name
|
149
|
+
when 'taskinator.process.created', 'taskinator.process.saved'
|
150
|
+
expect(payload[:state]).to eq(:initial)
|
151
|
+
when 'taskinator.process.processing'
|
152
|
+
expect(payload[:state]).to eq(:processing)
|
153
|
+
when 'taskinator.task.processing'
|
154
|
+
expect(payload[:state]).to eq(:processing)
|
155
|
+
when 'taskinator.task.completed'
|
156
|
+
expect(payload[:state]).to eq(:completed)
|
157
|
+
when 'taskinator.process.completed'
|
158
|
+
expect(payload[:state]).to eq(:completed)
|
159
|
+
else
|
160
|
+
raise "Unknown event '#{name}'."
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
allow(Taskinator).to receive(:instrumenter).and_return(instrumenter)
|
166
|
+
expect(instrumenter).to receive(:instrument).at_least(task_count).times.and_call_original
|
167
|
+
|
168
|
+
expect(subject.current_state).to eq(:initial)
|
169
|
+
|
170
|
+
subject.start!
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
describe "job" do
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
describe "subprocess" do
|
180
|
+
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
describe "instrumentation" do
|
185
|
+
describe "task" do
|
186
|
+
before do
|
187
|
+
# override enqueue
|
188
|
+
allow_any_instance_of(Taskinator::Task::Step).to receive(:enqueue!) { |task|
|
189
|
+
# emulate the worker starting the task
|
190
|
+
task.start!
|
191
|
+
}
|
192
|
+
end
|
193
|
+
|
194
|
+
let(:task_count) { 10 }
|
195
|
+
let(:definition) { TestFlows::Task }
|
196
|
+
subject { definition.create_process(task_count) }
|
197
|
+
|
198
|
+
it "reports task completed" do
|
199
|
+
block = SpecSupport::Block.new
|
200
|
+
expect(block).to receive(:call).exactly(task_count).times
|
201
|
+
|
202
|
+
TestInstrumenter.subscribe(block, /taskinator.task.completed/) do
|
203
|
+
subject.start!
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
it "reports process completed" do
|
208
|
+
block = SpecSupport::Block.new
|
209
|
+
expect(block).to receive(:call).once
|
210
|
+
|
211
|
+
TestInstrumenter.subscribe(block, /taskinator.process.completed/) do
|
212
|
+
subject.start!
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
it "reports task percentage completed" do
|
217
|
+
invoke_count = 0
|
218
|
+
|
219
|
+
instrumenter = TestInstrumenter.new do |name, payload|
|
220
|
+
if name =~ /taskinator.task.processing/
|
221
|
+
expect(payload[:percentage_completed]).to eq( (invoke_count / task_count.to_f) * 100.0 )
|
222
|
+
elsif name =~ /taskinator.task.completed/
|
223
|
+
invoke_count += 1
|
224
|
+
expect(payload[:percentage_completed]).to eq( (invoke_count / task_count.to_f) * 100.0 )
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
allow(Taskinator).to receive(:instrumenter).and_return(instrumenter)
|
229
|
+
expect(instrumenter).to receive(:instrument).at_least(task_count).times.and_call_original
|
230
|
+
|
231
|
+
subject.start!
|
232
|
+
end
|
233
|
+
|
234
|
+
it "reports process percentage completed" do
|
235
|
+
instrumenter = TestInstrumenter.new do |name, payload|
|
236
|
+
if name =~ /taskinator.process.started/
|
237
|
+
expect(payload[:process_uuid]).to eq(subject.uuid)
|
238
|
+
elsif name =~ /taskinator.process.completed/
|
239
|
+
expect(payload[:percentage_completed]).to eq(100.0)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
allow(Taskinator).to receive(:instrumenter).and_return(instrumenter)
|
244
|
+
expect(instrumenter).to receive(:instrument).at_least(task_count).times.and_call_original
|
245
|
+
|
246
|
+
subject.start!
|
247
|
+
end
|
248
|
+
|
249
|
+
end
|
250
|
+
|
251
|
+
describe "job" do
|
252
|
+
before do
|
253
|
+
# override enqueue
|
254
|
+
allow_any_instance_of(Taskinator::Task::Job).to receive(:enqueue!) { |task|
|
255
|
+
# emulate the worker starting the task
|
256
|
+
task.start!
|
257
|
+
}
|
258
|
+
end
|
259
|
+
|
260
|
+
let(:task_count) { 10 }
|
261
|
+
let(:definition) { TestFlows::Job }
|
262
|
+
subject { definition.create_process(task_count) }
|
263
|
+
|
264
|
+
it "reports task completed" do
|
265
|
+
block = SpecSupport::Block.new
|
266
|
+
expect(block).to receive(:call).exactly(task_count).times
|
267
|
+
|
268
|
+
TestInstrumenter.subscribe(block, /taskinator.task.completed/) do
|
269
|
+
subject.start!
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
it "reports process completed" do
|
274
|
+
block = SpecSupport::Block.new
|
275
|
+
expect(block).to receive(:call).once
|
276
|
+
|
277
|
+
TestInstrumenter.subscribe(block, /taskinator.process.completed/) do
|
278
|
+
subject.start!
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
it "reports task percentage completed" do
|
283
|
+
invoke_count = 0
|
284
|
+
|
285
|
+
instrumenter = TestInstrumenter.new do |name, payload|
|
286
|
+
if name =~ /taskinator.task.processing/
|
287
|
+
expect(payload[:percentage_completed]).to eq( (invoke_count / task_count.to_f) * 100.0 )
|
288
|
+
elsif name =~ /taskinator.task.completed/
|
289
|
+
invoke_count += 1
|
290
|
+
expect(payload[:percentage_completed]).to eq( (invoke_count / task_count.to_f) * 100.0 )
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
allow(Taskinator).to receive(:instrumenter).and_return(instrumenter)
|
295
|
+
expect(instrumenter).to receive(:instrument).at_least(task_count).times.and_call_original
|
296
|
+
|
297
|
+
subject.start!
|
298
|
+
end
|
299
|
+
|
300
|
+
it "reports process percentage completed" do
|
301
|
+
instrumenter = TestInstrumenter.new do |name, payload|
|
302
|
+
if name =~ /taskinator.process.started/
|
303
|
+
expect(payload[:process_uuid]).to eq(subject.uuid)
|
304
|
+
elsif name =~ /taskinator.process.completed/
|
305
|
+
expect(payload[:percentage_completed]).to eq(100.0)
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
allow(Taskinator).to receive(:instrumenter).and_return(instrumenter)
|
310
|
+
expect(instrumenter).to receive(:instrument).at_least(task_count).times.and_call_original
|
311
|
+
|
312
|
+
subject.start!
|
313
|
+
end
|
314
|
+
|
315
|
+
end
|
316
|
+
|
317
|
+
describe "sub process" do
|
318
|
+
before do
|
319
|
+
# override enqueue
|
320
|
+
allow_any_instance_of(Taskinator::Task::Step).to receive(:enqueue!) { |task|
|
321
|
+
# emulate the worker starting the task
|
322
|
+
task.start!
|
323
|
+
}
|
324
|
+
|
325
|
+
# override enqueue
|
326
|
+
allow_any_instance_of(Taskinator::Task::SubProcess).to receive(:enqueue!) { |task|
|
327
|
+
# emulate the worker starting the task
|
328
|
+
task.start!
|
329
|
+
}
|
330
|
+
end
|
331
|
+
|
332
|
+
let(:task_count) { 10 }
|
333
|
+
let(:definition) { TestFlows::SubProcess }
|
334
|
+
subject { definition.create_process(task_count) }
|
335
|
+
|
336
|
+
it "reports task completed" do
|
337
|
+
block = SpecSupport::Block.new
|
338
|
+
|
339
|
+
# NOTE: sub process counts for one task
|
340
|
+
expect(block).to receive(:call).exactly(task_count + 1).times
|
341
|
+
|
342
|
+
TestInstrumenter.subscribe(block, /taskinator.task.completed/) do
|
343
|
+
subject.start!
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
it "reports process completed" do
|
348
|
+
block = SpecSupport::Block.new
|
349
|
+
expect(block).to receive(:call).twice # includes sub process
|
350
|
+
|
351
|
+
TestInstrumenter.subscribe(block, /taskinator.process.completed/) do
|
352
|
+
subject.start!
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
it "reports task percentage completed" do
|
357
|
+
invoke_count = 0
|
358
|
+
|
359
|
+
instrumenter = TestInstrumenter.new do |name, payload|
|
360
|
+
if name =~ /taskinator.task.processing/
|
361
|
+
expect(payload[:percentage_completed]).to eq( (invoke_count / task_count.to_f) * 100.0 )
|
362
|
+
elsif name =~ /taskinator.task.completed/
|
363
|
+
unless payload.type >= Taskinator::Task::SubProcess
|
364
|
+
invoke_count += 1
|
365
|
+
expect(payload[:percentage_completed]).to eq( (invoke_count / task_count.to_f) * 100.0 )
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
allow(Taskinator).to receive(:instrumenter).and_return(instrumenter)
|
371
|
+
expect(instrumenter).to receive(:instrument).at_least(task_count).times.and_call_original
|
372
|
+
|
373
|
+
subject.start!
|
374
|
+
end
|
375
|
+
|
376
|
+
it "reports process percentage completed" do
|
377
|
+
instrumenter = TestInstrumenter.new do |name, payload|
|
378
|
+
if name =~ /taskinator.process.started/
|
379
|
+
expect(payload[:process_uuid]).to eq(subject.uuid)
|
380
|
+
elsif name =~ /taskinator.process.completed/
|
381
|
+
expect(payload[:percentage_completed]).to eq(100.0)
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
allow(Taskinator).to receive(:instrumenter).and_return(instrumenter)
|
386
|
+
|
387
|
+
# NOTE: sub process counts for one task
|
388
|
+
expect(instrumenter).to receive(:instrument).at_least(task_count + 1).times.and_call_original
|
389
|
+
|
390
|
+
subject.start!
|
391
|
+
end
|
392
|
+
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
131
396
|
end
|
data/taskinator.gemspec
CHANGED
@@ -25,25 +25,4 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_dependency 'redis-namespace' , '>= 1.5.2'
|
26
26
|
spec.add_dependency 'connection_pool' , '>= 2.2.0'
|
27
27
|
spec.add_dependency 'json' , '>= 1.8.2'
|
28
|
-
|
29
|
-
# spec.add_dependency 'workflow' , '>= 1.3.0' # RubyGems not up to date as of 11 Nov 2014.
|
30
|
-
|
31
|
-
# queues
|
32
|
-
spec.add_development_dependency 'sidekiq' , '>= 3.0.0'
|
33
|
-
spec.add_development_dependency 'rspec-sidekiq' , '>= 2.0.0'
|
34
|
-
|
35
|
-
spec.add_development_dependency 'delayed_job' , '>= 4.0.0'
|
36
|
-
|
37
|
-
spec.add_development_dependency 'resque' , '>= 1.25.2'
|
38
|
-
spec.add_development_dependency 'resque_spec' , '>= 0.16.0'
|
39
|
-
|
40
|
-
# other
|
41
|
-
spec.add_development_dependency 'bundler' , '>= 1.6.0'
|
42
|
-
spec.add_development_dependency 'rake' , '>= 10.3.0'
|
43
|
-
spec.add_development_dependency 'activesupport' , '>= 4.0.0'
|
44
|
-
spec.add_development_dependency 'rspec'
|
45
|
-
spec.add_development_dependency 'coveralls' , '>= 0.7.0'
|
46
|
-
spec.add_development_dependency 'pry' , '>= 0.9.0'
|
47
|
-
spec.add_development_dependency 'pry-byebug' , '>= 1.3.0'
|
48
|
-
|
49
28
|
end
|