Julio Biason
2 years ago
1 changed files with 85 additions and 0 deletions
@ -0,0 +1,85 @@
|
||||
+++ |
||||
title = "Thrifty Rubidium" |
||||
date = 2022-06-14 |
||||
|
||||
[taxonomies] |
||||
tags = ["projects", "personal", "make", "runner"] |
||||
+++ |
||||
|
||||
Task Runner. |
||||
|
||||
The basic idea is to have a bunch of tasks, and each task have a step. Based on |
||||
the parallelism available (number of cores, for example), the system would |
||||
launch each step on each task as long as there is available processing power. |
||||
|
||||
Let's start with the definition of task: A task could be, very simply, a |
||||
directory with a runner configuration file, where the steps are defined. For |
||||
example: |
||||
|
||||
```json |
||||
{ |
||||
"name": "ExampleTask", |
||||
"steps": [ |
||||
{ |
||||
"name": "Get List", |
||||
"command": "ls > file.ls" |
||||
}, |
||||
{ |
||||
"name": "Find file", |
||||
"command": "grep somename file.ls" |
||||
}, |
||||
{ |
||||
"name": "Remove file", |
||||
"command": "rm file.ls" |
||||
} |
||||
] |
||||
} |
||||
``` |
||||
|
||||
If one of the steps fails, the whole task stops. For example, if grep returns |
||||
an error code, "Rmeove file" would not be run. |
||||
|
||||
{% note() %} |
||||
**Thought**: Maybe we could add a flag on each step to point that the steps |
||||
should keep going even in case of error. |
||||
{% end %} |
||||
|
||||
The first step is to walk all directories, trying to find out which ones |
||||
contain the task configuration file. Once found, it will be added to the list |
||||
of running tasks, and the steps will start running. |
||||
|
||||
One multiple tasks we could have something like this |
||||
([TUI](https://github.com/fdehau/tui-rs) idea, also): |
||||
|
||||
``` |
||||
Task Step 1 Step 2 Step 3 Step 4 |
||||
ExampleTask Get list (R) Find file (W) Remove file (W) |
||||
Task2 Step21 (D) Step 22 (R) Step 23 (W) Step 24 (W) |
||||
Task3 Step31 (R) Step 32 (W) Step 33 (W) |
||||
Task4 Step41 (D) Step 42 (R) |
||||
Task5 Step51 (E) Step 52 (S) Step 53 (S) |
||||
``` |
||||
|
||||
In this example, there are 4 available cores, so only 4 steps can run at the |
||||
same time; those are marked as `(R)` for Running. Once the step is Done, marked |
||||
as `(D)`, task can move to the next step. Steps marked with `(W)` are Waiting |
||||
for their time to be run, which requires the previous step to be marked as Done |
||||
and having enough cores available. If a step errors, `(E)`, the task stops |
||||
running and the next steps are marked as Skipped, `(S)`. |
||||
|
||||
The structures to load the tasks is pretty simple: |
||||
|
||||
```rust |
||||
pub struct Case { |
||||
name: String, |
||||
steps: Vec<Step> |
||||
} |
||||
|
||||
pub struct Step { |
||||
name: String, |
||||
command: String, |
||||
} |
||||
``` |
||||
|
||||
After reading the data from the disk, the code could check if the step is "valid", |
||||
like checking if the command exists and can be called. |
Loading…
Reference in new issue