aaronriekenberg / rust-parallel

Fast command line app in rust/tokio to run commands in parallel. Similar interface to GNU parallel or xargs plus useful features. Listed in Awesome Rust utilities.
MIT License
146 stars 7 forks source link

Better ETA estimate #17

Open utkarshgupta137 opened 5 months ago

utkarshgupta137 commented 5 months ago

Currently, rust-parallel relies on indicatif to calculate ETAs for us, but the problem is that indicatif doesn't know the start times of the tasks, only the end times (when we increase the count). The problem with only knowing end times is that if a lot of tasks finish close to each other, then the ETA estimate decreases a lot suddenly & shoots back up too much when they don't complete for a while. This probably affects us more since we've a lot of large tasks (biggest being 30m & smallest being 2m). But we know before hand how long each is gonna take, so we order them in descending order before hand. But since the first few groups are similar in size, they would complete very close to each other & the ETA will look much smaller.

Example:

``` [00:09:04] Commands Done/Total: 1/938 ░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 5d 21:38:16 finished running task (8m58s) [00:09:04] Commands Done/Total: 2/938 ░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 2d 19:42:01 finished running task (8m58s) [00:09:04] Commands Done/Total: 3/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 13:11:37 finished running task (8m58s) [00:09:04] Commands Done/Total: 4/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 07:36:00 finished running task (8m58s) [00:09:04] Commands Done/Total: 5/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 07:33:08 finished running task (8m58s) [00:09:05] Commands Done/Total: 6/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 04:11:55 finished running task (8m58s) [00:09:44] Commands Done/Total: 7/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 09:41:32 finished running task (9m40s) [00:09:45] Commands Done/Total: 8/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 07:44:54 finished running task (9m40s) [00:17:13] Commands Done/Total: 9/938 ░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 4d 19:34:39 finished running task (8m2s) [00:17:14] Commands Done/Total: 10/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 12:04:12 finished running task (8m4s) [00:17:20] Commands Done/Total: 11/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 02:29:44 finished running task (8m10s) [00:17:30] Commands Done/Total: 12/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 02:19:42 finished running task (8m20s) [00:17:33] Commands Done/Total: 13/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 01:49:24 finished running task (8m23s) [00:17:39] Commands Done/Total: 14/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 01:34:05 finished running task (8m29s) [00:17:39] Commands Done/Total: 15/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 01:29:14 finished running task (17m34s) [00:17:39] Commands Done/Total: 16/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 01:22:28 finished running task (17m35s) [00:23:55] Commands Done/Total: 17/938 ░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 4d 00:05:00 finished running task (23m50s) [00:24:32] Commands Done/Total: 18/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 09:36:49 finished running task (24m28s) [00:24:34] Commands Done/Total: 19/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 04:35:09 finished running task (24m29s) [00:24:34] Commands Done/Total: 20/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 03:48:04 finished running task (24m29s) [00:24:57] Commands Done/Total: 21/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 04:52:35 finished running task (24m53s) [00:25:19] Commands Done/Total: 22/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 05:36:11 finished running task (7m36s) [00:25:19] Commands Done/Total: 23/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 05:35:06 finished running task (8m) [00:25:19] Commands Done/Total: 24/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 04:36:30 finished running task (7m35s) [00:25:20] Commands Done/Total: 25/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 03:47:52 finished running task (7m42s) [00:25:20] Commands Done/Total: 26/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 03:43:31 finished running task (7m54s) [00:25:20] Commands Done/Total: 27/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 03:33:13 finished running task (7m44s) [00:25:24] Commands Done/Total: 28/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 00:52:41 finished running task (7m41s) [00:25:27] Commands Done/Total: 29/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 00:44:04 finished running task (25m23s) [00:25:59] Commands Done/Total: 30/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 06:59:01 finished running task (25m55s) [00:27:03] Commands Done/Total: 31/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 16:06:59 finished running task (26m59s) [00:27:22] Commands Done/Total: 32/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 05:02:22 finished running task (27m17s) [00:27:24] Commands Done/Total: 33/938 ░░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 02:56:36 finished running task (17m35s) [00:27:25] Commands Done/Total: 34/938 █░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 02:27:33 finished running task (17m35s) [00:29:38] Commands Done/Total: 35/938 ░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 1d 09:32:09 finished running task (5m37s) [00:31:09] Commands Done/Total: 36/938 █░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 22:38:42 finished running task (31m4s) [00:31:19] Commands Done/Total: 37/938 █░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 03:46:50 finished running task (31m14s) [00:31:42] Commands Done/Total: 38/938 █░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 05:41:38 finished running task (7m5s) [00:31:42] Commands Done/Total: 39/938 █░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 05:23:35 finished running task (7m3s) [00:31:42] Commands Done/Total: 40/938 █░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 04:59:09 finished running task (6m41s) [00:31:42] Commands Done/Total: 41/938 █░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 04:38:00 finished running task (7m3s) [00:32:04] Commands Done/Total: 42/938 █░░░░░░░░░░░░░░░░░░░░░░░░░░░ ETA 04:01:15 finished running task (6m40s) ```

I think a better approach might be to have a simple logic like elapsed * (total - done) / done or slightly more complicated logic like EMA(time per task) * (total - done).

aaronriekenberg commented 5 months ago

Thanks for reporting @utkarshgupta137 .

Will see if it is possible to improve the ETA calculation that indicatif is doing.

If not one option could be to calculate the ETA on our own as you showed above. I think with_key can be used to draw custom elements in a progress bar as in this example: https://github.com/console-rs/indicatif/blob/main/examples/download.rs#L14