taskinator 0.4.2 → 0.4.3
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 +6 -0
- data/Gemfile.lock +23 -23
- data/README.md +169 -68
- data/lib/taskinator/api.rb +14 -5
- data/lib/taskinator/version.rb +1 -1
- data/spec/taskinator/api_spec.rb +16 -0
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f1a746ba56e5b6a2f57736990eef9e83eafe8701fcbebaaddea258a010f3ee14
|
|
4
|
+
data.tar.gz: 5e17bc8e6a61b93d6df0691dc463fb178aca72957ab79eccaea7b9cd6c1af642
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8f8cd10cc4c8f5d45d5cc781b379927bae7c0ed5c280e2470450a818a6a3132af75bc11a4c16eef6312056f984e912f3fa758bd45e493988cee37fd01ad92d87
|
|
7
|
+
data.tar.gz: f8b330d3f6e6766f6ddbc33becd3bb6d16826a021dd0ba16c3b2ec8308cdfe31caad40621fcbc542d6662c8aababaa946e369d251c82b24a213f955a942192a3
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
taskinator (0.4.
|
|
4
|
+
taskinator (0.4.3)
|
|
5
5
|
builder (>= 3.2.2)
|
|
6
6
|
connection_pool (>= 2.2.0)
|
|
7
7
|
globalid (~> 0.3)
|
|
@@ -14,7 +14,7 @@ PATH
|
|
|
14
14
|
GEM
|
|
15
15
|
remote: https://rubygems.org/
|
|
16
16
|
specs:
|
|
17
|
-
activesupport (5.2.
|
|
17
|
+
activesupport (5.2.6)
|
|
18
18
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
19
19
|
i18n (>= 0.7, < 2)
|
|
20
20
|
minitest (~> 5.1)
|
|
@@ -22,8 +22,8 @@ GEM
|
|
|
22
22
|
builder (3.2.4)
|
|
23
23
|
byebug (11.1.3)
|
|
24
24
|
coderay (1.1.3)
|
|
25
|
-
concurrent-ruby (1.1.
|
|
26
|
-
connection_pool (2.2.
|
|
25
|
+
concurrent-ruby (1.1.9)
|
|
26
|
+
connection_pool (2.2.5)
|
|
27
27
|
coveralls (0.8.23)
|
|
28
28
|
json (>= 1.8, < 3)
|
|
29
29
|
simplecov (~> 0.16.1)
|
|
@@ -32,36 +32,36 @@ GEM
|
|
|
32
32
|
tins (~> 1.6)
|
|
33
33
|
delayed_job (4.1.9)
|
|
34
34
|
activesupport (>= 3.0, < 6.2)
|
|
35
|
-
diff-lcs (1.
|
|
36
|
-
docile (1.
|
|
35
|
+
diff-lcs (1.5.0)
|
|
36
|
+
docile (1.4.0)
|
|
37
37
|
e2mmap (0.1.0)
|
|
38
38
|
fakeredis (0.7.0)
|
|
39
39
|
redis (>= 3.2, < 5.0)
|
|
40
|
-
globalid (0.
|
|
41
|
-
activesupport (>=
|
|
42
|
-
i18n (1.8.
|
|
40
|
+
globalid (0.6.0)
|
|
41
|
+
activesupport (>= 5.0)
|
|
42
|
+
i18n (1.8.11)
|
|
43
43
|
concurrent-ruby (~> 1.0)
|
|
44
|
-
json (2.
|
|
44
|
+
json (2.6.1)
|
|
45
45
|
method_source (1.0.0)
|
|
46
|
-
minitest (5.
|
|
47
|
-
mono_logger (1.1.
|
|
46
|
+
minitest (5.15.0)
|
|
47
|
+
mono_logger (1.1.1)
|
|
48
48
|
multi_json (1.15.0)
|
|
49
49
|
mustermann (1.1.1)
|
|
50
50
|
ruby2_keywords (~> 0.0.1)
|
|
51
|
-
pry (0.
|
|
51
|
+
pry (0.14.1)
|
|
52
52
|
coderay (~> 1.1)
|
|
53
53
|
method_source (~> 1.0)
|
|
54
|
-
pry-byebug (3.
|
|
54
|
+
pry-byebug (3.8.0)
|
|
55
55
|
byebug (~> 11.0)
|
|
56
|
-
pry (~> 0.
|
|
56
|
+
pry (~> 0.10)
|
|
57
57
|
rack (2.2.3)
|
|
58
58
|
rack-protection (2.1.0)
|
|
59
59
|
rack
|
|
60
|
-
rake (13.0.
|
|
61
|
-
redis (4.
|
|
60
|
+
rake (13.0.6)
|
|
61
|
+
redis (4.5.1)
|
|
62
62
|
redis-namespace (1.8.1)
|
|
63
63
|
redis (>= 3.0.4)
|
|
64
|
-
resque (2.
|
|
64
|
+
resque (2.2.0)
|
|
65
65
|
mono_logger (~> 1.0)
|
|
66
66
|
multi_json (~> 1.0)
|
|
67
67
|
redis-namespace (~> 1.6)
|
|
@@ -87,9 +87,9 @@ GEM
|
|
|
87
87
|
rspec-sidekiq (3.1.0)
|
|
88
88
|
rspec-core (~> 3.0, >= 3.0.0)
|
|
89
89
|
sidekiq (>= 2.4.0)
|
|
90
|
-
rspec-support (3.10.
|
|
91
|
-
ruby2_keywords (0.0.
|
|
92
|
-
sidekiq (6.1
|
|
90
|
+
rspec-support (3.10.3)
|
|
91
|
+
ruby2_keywords (0.0.5)
|
|
92
|
+
sidekiq (6.3.1)
|
|
93
93
|
connection_pool (>= 2.2.2)
|
|
94
94
|
rack (~> 2.0)
|
|
95
95
|
redis (>= 4.2.0)
|
|
@@ -107,12 +107,12 @@ GEM
|
|
|
107
107
|
sync (0.5.0)
|
|
108
108
|
term-ansicolor (1.7.1)
|
|
109
109
|
tins (~> 1.0)
|
|
110
|
-
thor (1.1
|
|
110
|
+
thor (1.2.1)
|
|
111
111
|
thread_safe (0.3.6)
|
|
112
112
|
thwait (0.2.0)
|
|
113
113
|
e2mmap
|
|
114
114
|
tilt (2.0.10)
|
|
115
|
-
tins (1.
|
|
115
|
+
tins (1.31.0)
|
|
116
116
|
sync
|
|
117
117
|
tzinfo (1.2.9)
|
|
118
118
|
thread_safe (~> 0.1)
|
data/README.md
CHANGED
|
@@ -5,21 +5,25 @@
|
|
|
5
5
|
[](https://codeclimate.com/github/virtualstaticvoid/taskinator)
|
|
6
6
|
[](https://coveralls.io/r/virtualstaticvoid/taskinator)
|
|
7
7
|
|
|
8
|
-
A simple orchestration library for running complex processes or workflows in Ruby.
|
|
9
|
-
|
|
10
|
-
for
|
|
8
|
+
A simple orchestration library for running complex processes or workflows in Ruby.
|
|
9
|
+
Processes are defined using a simple DSL, where the sequences and tasks are defined.
|
|
10
|
+
Processes can then be queued for execution. Sequences can be synchronous or asynchronous,
|
|
11
|
+
and the overall process can be monitored for completion or failure.
|
|
11
12
|
|
|
12
|
-
Processes and tasks are executed by background workers and you can use any one of the
|
|
13
|
+
Processes and tasks are executed by background workers and you can use any one of the
|
|
14
|
+
following gems:
|
|
13
15
|
|
|
14
16
|
* [resque](https://github.com/resque/resque)
|
|
15
17
|
* [sidekiq](https://github.com/mperham/sidekiq)
|
|
16
18
|
* [delayed_job](https://github.com/collectiveidea/delayed_job)
|
|
17
19
|
|
|
18
|
-
The configuration and state of each process and their respective tasks is stored using
|
|
20
|
+
The configuration and state of each process and their respective tasks is stored using
|
|
21
|
+
Redis key/values.
|
|
19
22
|
|
|
20
23
|
## Requirements
|
|
21
24
|
|
|
22
|
-
The latest MRI (2.1, 2.0) version. Other versions/VMs are untested but might work fine.
|
|
25
|
+
The latest MRI (2.1, 2.0) version. Other versions/VMs are untested but might work fine.
|
|
26
|
+
MRI 1.9 is not supported.
|
|
23
27
|
|
|
24
28
|
Redis 2.4 or greater is required.
|
|
25
29
|
|
|
@@ -68,7 +72,8 @@ module MyProcess
|
|
|
68
72
|
end
|
|
69
73
|
```
|
|
70
74
|
|
|
71
|
-
The `define_process` method optionally takes the list of expected arguments which are used
|
|
75
|
+
The `define_process` method optionally takes the list of expected arguments which are used
|
|
76
|
+
to validate the arguments supplied when creating a new process.
|
|
72
77
|
These should be specified with symbols.
|
|
73
78
|
|
|
74
79
|
```ruby
|
|
@@ -87,7 +92,8 @@ process = MyProcess.create_process Date.today, :option_1 => true
|
|
|
87
92
|
|
|
88
93
|
_NOTE:_ The current implementation performs a naive check on the count of arguments.
|
|
89
94
|
|
|
90
|
-
Next, specify the tasks with their corresponding implementation methods, that make up the
|
|
95
|
+
Next, specify the tasks with their corresponding implementation methods, that make up the
|
|
96
|
+
process, using the `task` method and providing the `method` to execute for the task.
|
|
91
97
|
|
|
92
98
|
```ruby
|
|
93
99
|
module MyProcess
|
|
@@ -108,7 +114,8 @@ module MyProcess
|
|
|
108
114
|
end
|
|
109
115
|
```
|
|
110
116
|
|
|
111
|
-
More complex processes may define sequential or concurrent steps, using the `sequential`
|
|
117
|
+
More complex processes may define sequential or concurrent steps, using the `sequential`
|
|
118
|
+
and `concurrent` methods respectively.
|
|
112
119
|
|
|
113
120
|
```ruby
|
|
114
121
|
module MyProcess
|
|
@@ -141,10 +148,15 @@ module MyProcess
|
|
|
141
148
|
end
|
|
142
149
|
```
|
|
143
150
|
|
|
144
|
-
It is likely that you already have worker classes for one of the queueing libraries,
|
|
151
|
+
It is likely that you already have worker classes for one of the queueing libraries,
|
|
152
|
+
such as resque or delayed_job, and wish to reuse them for executing them in the sequence
|
|
153
|
+
defined by the process definition.
|
|
145
154
|
|
|
146
|
-
Define a `job` step, providing the class of the worker, and then taskinator will execute
|
|
147
|
-
|
|
155
|
+
Define a `job` step, providing the class of the worker, and then taskinator will execute
|
|
156
|
+
that worker as part of the process definition.
|
|
157
|
+
|
|
158
|
+
The `job` step will be queued and executed on same queue as configured by `delayed_job`, or
|
|
159
|
+
that of the worker for `resque` and `sidekiq`.
|
|
148
160
|
|
|
149
161
|
```ruby
|
|
150
162
|
# E.g. A resque worker
|
|
@@ -168,8 +180,11 @@ module MyProcess
|
|
|
168
180
|
end
|
|
169
181
|
```
|
|
170
182
|
|
|
171
|
-
You can also define data driven tasks using the `for_each` method, which takes an iterator method
|
|
172
|
-
|
|
183
|
+
You can also define data driven tasks using the `for_each` method, which takes an iterator method
|
|
184
|
+
name as an argument.
|
|
185
|
+
|
|
186
|
+
The iterator method yields the parameters necessary for the task or job. Notice that the task
|
|
187
|
+
method takes a parameter in this case, which will be the return values provided by the iterator.
|
|
173
188
|
|
|
174
189
|
```ruby
|
|
175
190
|
module MyProcess
|
|
@@ -192,8 +207,9 @@ module MyProcess
|
|
|
192
207
|
end
|
|
193
208
|
```
|
|
194
209
|
|
|
195
|
-
It is possible to branch the process logic based on the options hash passed in when creating
|
|
196
|
-
The `options?` method takes the options key as an argument and calls the supplied
|
|
210
|
+
It is possible to branch the process logic based on the options hash passed in when creating
|
|
211
|
+
a process. The `options?` method takes the options key as an argument and calls the supplied
|
|
212
|
+
block if the option is present and it's value is _truthy_.
|
|
197
213
|
|
|
198
214
|
```ruby
|
|
199
215
|
module MyProcess
|
|
@@ -227,8 +243,11 @@ process2 = MyProcess.create_process
|
|
|
227
243
|
process2.tasks.count #=> 1
|
|
228
244
|
```
|
|
229
245
|
|
|
230
|
-
In addition, it is possible to transform the arguments used by a task or job, by including
|
|
231
|
-
|
|
246
|
+
In addition, it is possible to transform the arguments used by a task or job, by including
|
|
247
|
+
a `transform` step in the definition.
|
|
248
|
+
|
|
249
|
+
Similarly for the `for_each` method, `transform` takes a method name as an argument.
|
|
250
|
+
The transformer method must yield the new arguments as required.
|
|
232
251
|
|
|
233
252
|
```ruby
|
|
234
253
|
module MyProcess
|
|
@@ -273,7 +292,8 @@ module MyProcess
|
|
|
273
292
|
end
|
|
274
293
|
```
|
|
275
294
|
|
|
276
|
-
Any combination or nesting of `task`, `sequential`, `concurrent` and `for_each` steps are
|
|
295
|
+
Any combination or nesting of `task`, `sequential`, `concurrent` and `for_each` steps are
|
|
296
|
+
possible. E.g.
|
|
277
297
|
|
|
278
298
|
```ruby
|
|
279
299
|
module MyProcess
|
|
@@ -306,13 +326,17 @@ module MyProcess
|
|
|
306
326
|
end
|
|
307
327
|
```
|
|
308
328
|
|
|
309
|
-
In this example, the `work_step_begin` is executed, followed by the `work_step_all_at_once`
|
|
310
|
-
the sub process `MySubProcess` is created and
|
|
329
|
+
In this example, the `work_step_begin` is executed, followed by the `work_step_all_at_once`
|
|
330
|
+
steps which are executed concurrently, then the sub process `MySubProcess` is created and
|
|
331
|
+
executed, followed by the `work_step_one_by_one` tasks which are executed sequentially and
|
|
311
332
|
finally the `work_step_end` is executed.
|
|
312
333
|
|
|
313
|
-
It is also possible to embed conditional logic within the process definition stages in
|
|
314
|
-
|
|
315
|
-
|
|
334
|
+
It is also possible to embed conditional logic within the process definition stages in
|
|
335
|
+
order to produce steps based on the required logic.
|
|
336
|
+
|
|
337
|
+
All builder methods are available within the scope of the `define_process` block. These
|
|
338
|
+
methods include `args` and `options` which are passed into the `create_process` method
|
|
339
|
+
of the definition.
|
|
316
340
|
|
|
317
341
|
E.g.
|
|
318
342
|
|
|
@@ -332,7 +356,8 @@ module MyProcess
|
|
|
332
356
|
end
|
|
333
357
|
|
|
334
358
|
# when creating this proces, you supply to option when calling `create_process`
|
|
335
|
-
# in this example, 'args' will be an array [1,2,3]
|
|
359
|
+
# in this example, 'args' will be an array [1,2,3]
|
|
360
|
+
# and options will be a Hash {:send_notification => true}
|
|
336
361
|
MyProcess.create_process(1, 2, 3, :send_notification => true)
|
|
337
362
|
|
|
338
363
|
```
|
|
@@ -364,8 +389,12 @@ To best understand how arguments are handled, you need to break it down into 3 p
|
|
|
364
389
|
* Creation and
|
|
365
390
|
* Execution
|
|
366
391
|
|
|
367
|
-
Firstly, a process definition is declarative in that the `define_process` and a mix of
|
|
368
|
-
|
|
392
|
+
Firstly, a process definition is declarative in that the `define_process` and a mix of
|
|
393
|
+
`sequential`, `concurrent`, `for_each`, `task` and `job` directives provide the way to
|
|
394
|
+
specify the sequencing of the steps for the process.
|
|
395
|
+
|
|
396
|
+
Taskinator will interprete this definition and execute each step in the desired sequence
|
|
397
|
+
or concurrency.
|
|
369
398
|
|
|
370
399
|
Consider the following process definition:
|
|
371
400
|
|
|
@@ -411,11 +440,17 @@ end
|
|
|
411
440
|
|
|
412
441
|
There are three tasks; namely `:work_step_1`, `:work_step_2` and `:work_step_3`.
|
|
413
442
|
|
|
414
|
-
The third task, `:work_step_3`, is built up using the `for_each` iterator, which means that
|
|
443
|
+
The third task, `:work_step_3`, is built up using the `for_each` iterator, which means that
|
|
444
|
+
the number of `:work_step_3` tasks will depend on how many times the `additional_step`
|
|
445
|
+
iterator method yields to the definition.
|
|
446
|
+
|
|
447
|
+
This brings us to the creation part. When `create_process` is called on the given module,
|
|
448
|
+
you provide arguments to it, which will get passed onto the respective `task` and
|
|
449
|
+
`for_each` iterator methods.
|
|
415
450
|
|
|
416
|
-
|
|
451
|
+
So, considering the `MySimpleProcess` module shown above, `work_step_1`, `work_step_2`
|
|
452
|
+
and `work_step_3` methods each expect arguments.
|
|
417
453
|
|
|
418
|
-
So, considering the `MySimpleProcess` module shown above, `work_step_1`, `work_step_2` and `work_step_3` methods each expect arguments.
|
|
419
454
|
These will ultimately come from the arguments passed into the `create_process` method.
|
|
420
455
|
|
|
421
456
|
E.g.
|
|
@@ -438,7 +473,8 @@ process = MySimpleProcess.create_process(options)
|
|
|
438
473
|
|
|
439
474
|
```
|
|
440
475
|
|
|
441
|
-
To best understand how the process is created, consider the following "procedural" code
|
|
476
|
+
To best understand how the process is created, consider the following "procedural" code
|
|
477
|
+
for how it could work.
|
|
442
478
|
|
|
443
479
|
```ruby
|
|
444
480
|
# A process, which maps the target and a list of steps
|
|
@@ -535,11 +571,17 @@ process.execute
|
|
|
535
571
|
|
|
536
572
|
```
|
|
537
573
|
|
|
538
|
-
In reality, each task is executed by a worker process, possibly on another host, so the
|
|
574
|
+
In reality, each task is executed by a worker process, possibly on another host, so the
|
|
575
|
+
execution process isn't as simple, but this example should help you to understand
|
|
576
|
+
conceptually how the process is executed, and how the arguments are propagated through.
|
|
539
577
|
|
|
540
578
|
### Monitoring
|
|
541
579
|
|
|
542
|
-
|
|
580
|
+
NOTE: This aspect of the library is still a work in progress.
|
|
581
|
+
|
|
582
|
+
#### Processes
|
|
583
|
+
|
|
584
|
+
To monitor the state of the processes, use the `Taskinator::Api::Processes` class.
|
|
543
585
|
|
|
544
586
|
```ruby
|
|
545
587
|
processes = Taskinator::Api::Processes.new
|
|
@@ -549,11 +591,57 @@ processes.each do |process|
|
|
|
549
591
|
end
|
|
550
592
|
```
|
|
551
593
|
|
|
594
|
+
#### Debugging
|
|
595
|
+
|
|
596
|
+
To aid debugging specific processes and tasks, where the process or task identifier is
|
|
597
|
+
known, it is possible to retrieve the specific task or process using `Taskinator::Api`.
|
|
598
|
+
|
|
599
|
+
To retrieve a specific process, given the process identifier:
|
|
600
|
+
|
|
601
|
+
```ruby
|
|
602
|
+
process_id = "SUPPLY-PROCESS-IDENTIFIER"
|
|
603
|
+
process = Taskinator::Api.find_process(process_id)
|
|
604
|
+
|
|
605
|
+
puts process.inspect
|
|
606
|
+
puts process.current_state
|
|
607
|
+
puts process.tasks
|
|
608
|
+
# etc...
|
|
609
|
+
```
|
|
610
|
+
|
|
611
|
+
The type of process may be one of the following:
|
|
612
|
+
|
|
613
|
+
* `Taskinator::Process::Sequential`
|
|
614
|
+
* `Taskinator::Process::Concurrent`
|
|
615
|
+
|
|
616
|
+
Then, to retrieve a specific task, given the task identifier:
|
|
617
|
+
|
|
618
|
+
```ruby
|
|
619
|
+
task_id = "SUPPLY-TASK-IDENTIFIER"
|
|
620
|
+
task = Taskinator::Api.find_task(task_id)
|
|
621
|
+
|
|
622
|
+
puts task.inspect
|
|
623
|
+
puts task.class
|
|
624
|
+
puts task.args # for Step and Job types
|
|
625
|
+
puts task.sub_process.tasks # for SubProcess type
|
|
626
|
+
# etc...
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
Depending on the type of task, different attributes will be available for inspection.
|
|
630
|
+
|
|
631
|
+
The types include:
|
|
632
|
+
|
|
633
|
+
* `Taskinator::Task::Step`
|
|
634
|
+
* `Taskinator::Task::Job`
|
|
635
|
+
* `Taskinator::Task::SubProcess`
|
|
636
|
+
|
|
552
637
|
## Configuration
|
|
553
638
|
|
|
554
639
|
### Redis
|
|
555
640
|
|
|
556
|
-
By default Taskinator assumes Redis is located at `localhost:6397`. This is fine for development,
|
|
641
|
+
By default Taskinator assumes Redis is located at `localhost:6397`. This is fine for development,
|
|
642
|
+
but for many production environments you will need to point to an external Redis server.
|
|
643
|
+
You may also what to use a namespace for the Redis keys.
|
|
644
|
+
|
|
557
645
|
_NOTE:_ The configuration hash _must_ have symbolized keys.
|
|
558
646
|
|
|
559
647
|
```ruby
|
|
@@ -568,15 +656,19 @@ end
|
|
|
568
656
|
Or, alternatively, via an `ENV` variable
|
|
569
657
|
|
|
570
658
|
Set the `REDIS_PROVIDER` environment variable to the Redis server url.
|
|
571
|
-
E.g. On Heroku, with RedisGreen: set REDIS_PROVIDER=REDISGREEN_URL and Taskinator will use the
|
|
659
|
+
E.g. On Heroku, with RedisGreen: set REDIS_PROVIDER=REDISGREEN_URL and Taskinator will use the
|
|
660
|
+
value of the `REDISGREEN_URL` environment variable when connecting to Redis.
|
|
572
661
|
|
|
573
662
|
You may also use the generic `REDIS_URL` which may be set to your own private Redis server.
|
|
574
663
|
|
|
575
|
-
The Redis configuration leverages the same setup as `sidekiq`. For advanced options, checkout the
|
|
664
|
+
The Redis configuration leverages the same setup as `sidekiq`. For advanced options, checkout the
|
|
665
|
+
[Sidekiq Advanced Options](https://github.com/mperham/sidekiq/wiki/Advanced-Options#complete-control)
|
|
666
|
+
wiki page for more information.
|
|
576
667
|
|
|
577
668
|
### Queues
|
|
578
669
|
|
|
579
|
-
By default the queue names for process and task workers is `default`, however, you can specify
|
|
670
|
+
By default the queue names for process and task workers is `default`, however, you can specify
|
|
671
|
+
the queue names as follows:
|
|
580
672
|
|
|
581
673
|
```ruby
|
|
582
674
|
Taskinator.configure do |config|
|
|
@@ -589,7 +681,8 @@ end
|
|
|
589
681
|
|
|
590
682
|
### Instrumentation
|
|
591
683
|
|
|
592
|
-
It is possible to instrument processes, tasks and jobs by providing an instrumeter such
|
|
684
|
+
It is possible to instrument processes, tasks and jobs by providing an instrumeter such
|
|
685
|
+
as `ActiveSupport::Notifications`.
|
|
593
686
|
|
|
594
687
|
```ruby
|
|
595
688
|
Taskinator.configure do |config|
|
|
@@ -607,40 +700,41 @@ end
|
|
|
607
700
|
|
|
608
701
|
The following instrumentation events are issued:
|
|
609
702
|
|
|
610
|
-
| Event
|
|
611
|
-
|
|
612
|
-
| `taskinator.process.created`
|
|
613
|
-
| `taskinator.process.saved`
|
|
614
|
-
| `taskinator.process.enqueued`
|
|
615
|
-
| `taskinator.process.processing`
|
|
616
|
-
| `taskinator.process.paused`
|
|
617
|
-
| `taskinator.process.resumed`
|
|
618
|
-
| `taskinator.process.completed`
|
|
619
|
-
| `taskinator.process.cancelled`
|
|
620
|
-
| `taskinator.process.failed`
|
|
621
|
-
| `taskinator.task.enqueued`
|
|
622
|
-
| `taskinator.task.processing`
|
|
623
|
-
| `taskinator.task.completed`
|
|
624
|
-
| `taskinator.task.cancelled`
|
|
625
|
-
| `taskinator.task.failed`
|
|
703
|
+
| Event | When |
|
|
704
|
+
|---------------------------------|----------------------------------------------------------|
|
|
705
|
+
| `taskinator.process.created` | After a root process gets created |
|
|
706
|
+
| `taskinator.process.saved` | After a root process has been persisted to Redis |
|
|
707
|
+
| `taskinator.process.enqueued` | After a process or subprocess is enqueued for processing |
|
|
708
|
+
| `taskinator.process.processing` | When a process or subprocess is processing |
|
|
709
|
+
| `taskinator.process.paused` | When a process or subprocess is paused |
|
|
710
|
+
| `taskinator.process.resumed` | When a process or subprocess is resumed |
|
|
711
|
+
| `taskinator.process.completed` | After a process or subprocess has completed processing |
|
|
712
|
+
| `taskinator.process.cancelled` | After a process or subprocess has been cancelled |
|
|
713
|
+
| `taskinator.process.failed` | After a process or subprocess has failed |
|
|
714
|
+
| `taskinator.task.enqueued` | After a task has been enqueued |
|
|
715
|
+
| `taskinator.task.processing` | When a task is processing |
|
|
716
|
+
| `taskinator.task.completed` | After a task has completed |
|
|
717
|
+
| `taskinator.task.cancelled` | After a task has been cancelled |
|
|
718
|
+
| `taskinator.task.failed` | After a task has failed |
|
|
626
719
|
|
|
627
720
|
For all events, the data included contains the following information:
|
|
628
721
|
|
|
629
|
-
| Key
|
|
630
|
-
|
|
631
|
-
| `:type`
|
|
632
|
-
| `:process_uuid`
|
|
633
|
-
| `:process_options`
|
|
634
|
-
| `:uuid`
|
|
635
|
-
| `:options`
|
|
636
|
-
| `:state`
|
|
637
|
-
| `:percentage_completed`
|
|
638
|
-
| `:percentage_failed`
|
|
639
|
-
| `:percentage_cancelled`
|
|
722
|
+
| Key | Value |
|
|
723
|
+
|---------------------------------|----------------------------------------------------------|
|
|
724
|
+
| `:type` | The type name of the component reporting the event |
|
|
725
|
+
| `:process_uuid` | The UUID of the root process |
|
|
726
|
+
| `:process_options` | Options hash of the root process |
|
|
727
|
+
| `:uuid` | The UUID of the respective task, job or sub process |
|
|
728
|
+
| `:options` | Options hash of the component |
|
|
729
|
+
| `:state` | State of the component |
|
|
730
|
+
| `:percentage_completed` | The percentage of completed tasks |
|
|
731
|
+
| `:percentage_failed` | The percentage of failed tasks |
|
|
732
|
+
| `:percentage_cancelled` | The percentage of cancelled tasks |
|
|
640
733
|
|
|
641
734
|
## Notes
|
|
642
735
|
|
|
643
|
-
The persistence logic is decoupled from the implementation, so it is possible to implement
|
|
736
|
+
The persistence logic is decoupled from the implementation, so it is possible to implement
|
|
737
|
+
another backing store if required.
|
|
644
738
|
|
|
645
739
|
## Contributing
|
|
646
740
|
|
|
@@ -651,12 +745,19 @@ The persistence logic is decoupled from the implementation, so it is possible to
|
|
|
651
745
|
5. Create new Pull Request
|
|
652
746
|
|
|
653
747
|
## License
|
|
748
|
+
|
|
654
749
|
MIT Copyright (c) 2014 Chris Stefano
|
|
655
750
|
|
|
656
751
|
Portions of code are from the Sidekiq project, Copyright (c) Contributed Systems LLC.
|
|
657
752
|
|
|
658
753
|
## Inspiration
|
|
659
754
|
|
|
660
|
-
Inspired by the [sidekiq](https://github.com/mperham/sidekiq) and
|
|
755
|
+
Inspired by the [sidekiq](https://github.com/mperham/sidekiq) and
|
|
756
|
+
[workflow](https://github.com/geekq/workflow) gems.
|
|
757
|
+
|
|
758
|
+
For other workflow solutions, checkout [Stonepath](https://github.com/bokmann/stonepath),
|
|
759
|
+
the now deprecated [ruote](https://github.com/jmettraux/ruote) gem and
|
|
760
|
+
[workflow](https://github.com/geekq/workflow).
|
|
661
761
|
|
|
662
|
-
|
|
762
|
+
Alternatively, for a robust enterprise ready solution checkout the
|
|
763
|
+
[AWS Flow Framework for Ruby](http://docs.aws.amazon.com/amazonswf/latest/awsrbflowguide/welcome.html).
|
data/lib/taskinator/api.rb
CHANGED
|
@@ -13,12 +13,13 @@ module Taskinator
|
|
|
13
13
|
def each(&block)
|
|
14
14
|
return to_enum(__method__) unless block_given?
|
|
15
15
|
|
|
16
|
+
identifiers = Taskinator.redis do |conn|
|
|
17
|
+
conn.smembers(@processes_list_key)
|
|
18
|
+
end
|
|
19
|
+
|
|
16
20
|
instance_cache = {}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
uuids.each do |uuid|
|
|
20
|
-
yield Process.fetch(uuid, instance_cache)
|
|
21
|
-
end
|
|
21
|
+
identifiers.each do |identifier|
|
|
22
|
+
yield Process.fetch(identifier, instance_cache)
|
|
22
23
|
end
|
|
23
24
|
end
|
|
24
25
|
|
|
@@ -28,5 +29,13 @@ module Taskinator
|
|
|
28
29
|
end
|
|
29
30
|
end
|
|
30
31
|
end
|
|
32
|
+
|
|
33
|
+
def self.find_process(identifier)
|
|
34
|
+
Process.fetch(identifier)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.find_task(identifier)
|
|
38
|
+
Task.fetch(identifier)
|
|
39
|
+
end
|
|
31
40
|
end
|
|
32
41
|
end
|
data/lib/taskinator/version.rb
CHANGED
data/spec/taskinator/api_spec.rb
CHANGED
|
@@ -44,4 +44,20 @@ describe Taskinator::Api, :redis => true do
|
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
+
describe "#find_process" do
|
|
48
|
+
it {
|
|
49
|
+
# fetch method is covered by persistence spec
|
|
50
|
+
expect(Taskinator::Process).to receive(:fetch) {}
|
|
51
|
+
subject.find_process 'foo:bar:process'
|
|
52
|
+
}
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
describe "#find_task" do
|
|
56
|
+
it {
|
|
57
|
+
# fetch method is covered by persistence spec
|
|
58
|
+
expect(Taskinator::Task).to receive(:fetch) {}
|
|
59
|
+
subject.find_task 'foo:bar:process:baz:task'
|
|
60
|
+
}
|
|
61
|
+
end
|
|
62
|
+
|
|
47
63
|
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.4.
|
|
4
|
+
version: 0.4.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chris Stefano
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-01-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: redis
|
|
@@ -232,7 +232,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
232
232
|
- !ruby/object:Gem::Version
|
|
233
233
|
version: '0'
|
|
234
234
|
requirements: []
|
|
235
|
-
rubygems_version: 3.
|
|
235
|
+
rubygems_version: 3.2.3
|
|
236
236
|
signing_key:
|
|
237
237
|
specification_version: 4
|
|
238
238
|
summary: A simple orchestration library for running complex processes or workflows
|