1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
use crate;
use ;
use Ctx;
use Job;
use BinCommand;
use debug;
use Profile;
use HashMap;
/// Represents and contains a given runtime.
///
/// This object contains an ordered list of [`jobs`], each job containing an ordered list of tasks,
/// each task containing one or more concurrent processes. This object also contains a [`ctx`]
/// object which contains the binary command and args for the current runtime as well as hashmap
/// indexes for processes and log monitors which are copied to each child job, task, and process so
/// that the runtime can instantiate new processes and log monitors on the fly.
///
/// A visual representation:
///
/// ```text
/// Runtime
/// T |
/// I > [ Job1, Job2, ... ]
/// M |
/// E > [ Task1, Task2, ... ]
/// |
/// | > Process1 -> `echo foo`
/// | | |
/// | | > OnSucceed: Process2 -> `echo bar`
/// v |
/// > Process2 -> `echo bar`
///
/// ...
///
/// Runtime
/// |
/// > [ Job1, Job2, ... ]
/// |
/// > [ Task1, Task2, ... ]
/// |
/// > Process3 -> `echo baz`
///
/// ...
///
/// Runtime
/// |
/// > [ Job1, Job2, ... ]
/// |
/// > [ Task1, ... ]
/// |
/// > Process4 -> `echo qux`
/// ```
///
/// Processes in a given task run concurrently.
///
/// Once all processes in the task have exited, including actions (`onsucceed`, `onfail`, and log
/// monitor `ontrigger` actions spawned on their parent process threads), the task is complete and
/// the next task in the job will execute.
///
/// Once all tasks in a given job have completed their execution, the runtime moves on to the next
/// job in the queue. Once all jobs have completed their execution, the runtime is finished.
///
/// [`jobs`]: #structfield.jobs
/// [`ctx`]: #structfield.ctx
///
/// # Examples:
///
/// Basic usage:
///
/// ```
/// use arpx::{Job, Process, Runtime, Task};
/// use std::collections::HashMap;
///
/// let processes = vec![
/// Process::new("p_foo".to_string())
/// .command("echo foo".to_string())
/// .onsucceed(Some("p_baz".to_string())),
/// Process::new("p_bar".to_string()).command("echo bar".to_string()),
/// ];
///
/// let mut process_map = processes
/// .clone()
/// .into_iter()
/// .map(|process| (process.name.clone(), process))
/// .collect::<HashMap<String, Process>>();
///
/// process_map.insert(
/// "p_baz".to_string(),
/// Process::new("p_baz".to_string()).command("echo baz".to_string()),
/// );
///
/// let jobs = vec![Job::new(
/// "my_job".to_string(),
/// vec![Task::new(processes)],
/// )];
///
/// Runtime::new()
/// .jobs(jobs)
/// .process_map(process_map)
/// .run();
///
/// // Output:
/// //
/// // [p_foo] "p_foo" (1) spawned
/// // [p_bar] "p_bar" (2) spawned
/// // [p_foo] foo
/// // [p_bar] bar
/// // [p_foo] "p_foo" (1) succeeded
/// // [p_bar] "p_bar" (2) succeeded
/// // [p_foo] "p_baz" (3) spawned
/// // [p_foo] baz
/// // [p_foo] "p_baz" (3) succeeded
/// ```
///
/// Note that `p_baz` runs on the `p_foo` thread, since `p_foo` executes it `onsucceed`.