jongleur 1.1.0 → 1.1.1
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 +5 -0
- data/README.md +23 -15
- data/lib/jongleur/api.rb +14 -7
- data/lib/jongleur/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5601cb9eab89d7222a573523813c5ab64a5beba1
|
4
|
+
data.tar.gz: a147ad7182a1e4aa06ce2bfb9de56a50cf573903
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: abd107a4109aecdabf779b775e0628c3a92ce6efd87129ecece67b6e672be2296eb3c6a8eeda55cd2e9884c3cbd0e72e34d5f66a23d249d95ea56c787de736c0
|
7
|
+
data.tar.gz: 141c79dbda2a86b74fdcbd2cbf25fa993576189b4655bceece1b9f304aac0899e7fd794b2226ac493b0ed31f21b3b95b923c95469e9e8e6f21519172f3e4ad82
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -12,9 +12,9 @@ Jongleur is particularly useful for implementing workflows modelled as a [DAG](h
|
|
12
12
|
This gem has been built using the [POSIX/UNIX process model](https://support.sas.com/documentation/onlinedoc/sasc/doc750/html/lr2/zid-6574.htm).
|
13
13
|
It will work on Linux and Mac OS but not on Windows.
|
14
14
|
|
15
|
-
Jongleur has been tested with MRuby 2.4.3, 2.4.4, 2.5.0 and 2.5.1. I would also expect it to work with other Ruby implementations too,
|
15
|
+
Jongleur has been tested with MRuby 2.4.3, 2.4.4, 2.5.0 and 2.5.1. I would also expect it to work with other Ruby implementations too, though it hasn't yet been tested on those.
|
16
16
|
|
17
|
-
##
|
17
|
+
## Depndencies
|
18
18
|
|
19
19
|
This gem depends on the [Graphviz](https://www.graphviz.org/) package for drawing graphs. If this isn't already installed on your system please install with
|
20
20
|
|
@@ -45,32 +45,41 @@ In either case, call `require jongleur` before using the gem.
|
|
45
45
|
|
46
46
|
## What does it do?
|
47
47
|
|
48
|
-
In a nutshell, Jongleur keeps track of a number of tasks and executes them as separate OS processes according to their precedence criteria. For instance, if there are 3 tasks A, B and C, and task C depends on A and B, Jongleur will start executing A and B in separate processes (i.e
|
48
|
+
In a nutshell, Jongleur keeps track of a number of tasks and executes them as separate OS processes according to their precedence criteria. For instance, if there are 3 tasks A, B and C, and task C depends on A and B, Jongleur will start executing A and B in separate processes (i.e. in parallel) and will wait until they are both finished before it executes C in a separate process.
|
49
49
|
|
50
50
|
Jongleur is ideal for running workflows represented as DAGs, but is also useful for simply running tasks in parallel or for whenever you need some multi-processing capability.
|
51
51
|
|
52
52
|
## Concepts
|
53
53
|
|
54
|
+
### Directed Acyclic Graph (DAG)
|
55
|
+
A graph that is directed and without cycles connecting the other edges. DAGs are very useful for representing different kinds of information models, such as task scheduling and business process workflows.
|
56
|
+
|
54
57
|
### Task Graph
|
55
58
|
|
56
59
|
To run Jongleur, you will need to define the tasks to run and their precedence. A _Task Graph_ is a
|
57
|
-
representation of the tasks to be run by Jongleur and it usually (but not exclusively) represents a DAG, as in the
|
60
|
+
representation of the tasks to be run by Jongleur and it usually (but not exclusively) represents a DAG, as in the example below:
|
61
|
+
|
62
|
+

|
58
63
|
|
59
|
-

|
60
64
|
|
61
65
|
A _Task Graph_ is defined as a Hash in the following format:
|
62
66
|
|
63
67
|
`{task-name => list[names-of-dependent-tasks]}`
|
64
68
|
|
65
69
|
|
66
|
-
So the
|
70
|
+
So the graph above can be defined as:
|
67
71
|
|
68
72
|
```
|
69
73
|
my_graph = {
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
+
A: [:C, :D],
|
75
|
+
B: [:D, :E],
|
76
|
+
D: [:F, :G],
|
77
|
+
E: [],
|
78
|
+
C: [],
|
79
|
+
G: [:I],
|
80
|
+
H: [:I],
|
81
|
+
F: [],
|
82
|
+
I: []
|
74
83
|
}
|
75
84
|
|
76
85
|
```
|
@@ -78,12 +87,11 @@ my_graph = {
|
|
78
87
|
where they Hash key is the class name of a Task and the Hash value is an Array of other Tasks that can be
|
79
88
|
run only after this Task is finished. So in the above example:
|
80
89
|
|
81
|
-
* Tasks
|
82
|
-
* Task
|
83
|
-
* Tasks
|
84
|
-
|
85
|
-
__N.B:__ Since the _Task Graph_ is a Hash, any duplicate key entries will be overridden. For instance, if this Task Graph
|
90
|
+
* Tasks C and D can only start after task A has finished.
|
91
|
+
* Task I can only start after G and H have finished.
|
92
|
+
* Tasks C, E, F and I have no dependants. No other tasks need wait for them.
|
86
93
|
|
94
|
+
__N.B:__ Since the _Task Graph_ is a Hash, any duplicate key entries will be overridden. For instance:
|
87
95
|
```
|
88
96
|
my_task_graph = { A: [:B, :C], B: [:D] }
|
89
97
|
```
|
data/lib/jongleur/api.rb
CHANGED
@@ -131,6 +131,7 @@ module Jongleur
|
|
131
131
|
|
132
132
|
Implementation.process_message 'Starting workflow...'
|
133
133
|
trap_quit_signals
|
134
|
+
@finished_tasks_queue = []
|
134
135
|
start_processes
|
135
136
|
|
136
137
|
trap(:CHLD) do
|
@@ -146,6 +147,7 @@ module Jongleur
|
|
146
147
|
t.success_status = status.success?
|
147
148
|
t.finish_time = finish_time
|
148
149
|
dead_task_name = t.name
|
150
|
+
@finished_tasks_queue << { name: dead_task_name, done: status.success?, pid: dead_pid}
|
149
151
|
end
|
150
152
|
msg = "finished task: %s, process: %i, exit_status: %i, success: %s"
|
151
153
|
Implementation.process_message msg % [dead_task_name,
|
@@ -153,12 +155,7 @@ module Jongleur
|
|
153
155
|
status.exitstatus,
|
154
156
|
status.success?]
|
155
157
|
|
156
|
-
|
157
|
-
Implementation.run_descendants(dead_task_name)
|
158
|
-
else
|
159
|
-
msg = "Task #{dead_task_name} with process id #{dead_pid} was not succesfully completed."
|
160
|
-
Implementation.process_message(msg)
|
161
|
-
end
|
158
|
+
|
162
159
|
end
|
163
160
|
|
164
161
|
# it's possible for the last CHLD signal to arrive after our trap
|
@@ -167,9 +164,19 @@ module Jongleur
|
|
167
164
|
# the oncoming exception so we don't get a crash.
|
168
165
|
rescue Errno::ECHILD
|
169
166
|
end
|
170
|
-
end
|
167
|
+
end #trap
|
171
168
|
|
172
169
|
loop do
|
170
|
+
# run task's descendants as soon as task appears on 'finished' queue
|
171
|
+
while task = @finished_tasks_queue.pop
|
172
|
+
if task[:done]
|
173
|
+
Implementation.run_descendants(task[:name])
|
174
|
+
else
|
175
|
+
msg = "Task #{task[:name]} with process id #{task[:pid]} was not succesfully completed."
|
176
|
+
Implementation.process_message(msg)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
173
180
|
# We exit once all the child processes and their descendants are accounted for
|
174
181
|
if Implementation.running_tasks.empty?
|
175
182
|
Implementation.process_message 'Workflow finished'
|
data/lib/jongleur/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jongleur
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fred Heath
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphviz
|