taskinator 0.4.2 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Code Climate](https://codeclimate.com/github/virtualstaticvoid/taskinator.png)](https://codeclimate.com/github/virtualstaticvoid/taskinator)
|
6
6
|
[![Coverage Status](https://coveralls.io/repos/virtualstaticvoid/taskinator/badge.png)](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
|