-
Notifications
You must be signed in to change notification settings - Fork 481
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Is there a way to run independent tasks in parallel #626
Comments
It isn't possible at the moment, but I think this would be a cool feature. I think the best way to implement it would be to add annotations, and then define an annotation that makes a recipe run in the background. |
@casey I'm absolutely in love with using a Almost every npm script I write uses Keep up the great work friend! Cheers 🍻 |
Thanks Robert, I appreciate kind words! I'm glad to learn about I think that there are a few features that are languishing, awaiting annotations. I've been dragging my heels on adding annotations, but since there are a bunch of worthy features that need them, hopefully I'll get around to it sooner rather than later. |
No worries, nothing but time around here. lol I ended up replicating somewhat of the same workflow in combination with Nukesor/pueue 😂 |
Definitely sub-optimal than having it built into Just, but glad you found something that works! I'll have to check out pueue, it looks dope. |
My solution is to have a just command that's invoking make that's invoking just. 😄 It works. Dunno whether it should work. |
I think I misunderstood this motivation behind this feature, and thus how it might be implemented. Is the desire to run some recipes in a justfile in parallel, or all recipes in parallel? Let's call the former selective parallelism, and the latter universal parallelism. I was thinking that people wanted selective paralellism, so perhaps you could annotate a recipe to say that its dependencies should run in parallel. So, for example, to run
But, I think people actually want universal parallelism, people want to run all recipes in a justfile in parallel, or at least be able to pass a flag that all recipes should run in parallel. I think this latter behavior is probably more useful, since it requires fewer annotations and thought on the part of users, and since parallelism could be selectively limited through the use of dependency constraints. Currently, Just runs dependencies of a recipe in-order (barring dependencies between those dependencies), which users might have come to rely on. There are a few possibilities:
Does this seem like a good summary of what people want? |
For my use case, from #676 I want selective parallelism, and I'd prefer to have this specified in a target. Command line parameters remove some of the usefulness of "just" remembering what I want. |
Can you elaborate on why universal parallelism is undesirable, or why it would break the justfile? |
I collect many different types of tasks in my justfile, these have different running requirements.
That said, I guess it depends on how the parallelism is specified. My sequential tasks don't use dependencies, they instead do recursive invocation of "just". Thinking about that, perhaps a --parallel flag would be okay for my case, since I would have a target the invokes "just" with that flag, specifying the targets I want. That is, I think the details of how this is implemented will decide whether it's an issue or not. |
The question that I'm most curious about is whether or not people are depending on the fact that dependencies of a recipe without interdependencies run in order. I'm guessing that they don't, and most people use explicit dependencies to order recipes that cannot run in parallel. The reason I'm interested in that is because if people don't rely on this implicit dependency ordering, then command line flags or config options make a lot more sense, since justfiles wouldn't be likely to break if they suddenly ran in parallel. I definitely agree that command-line flags are less convenient. I think a command-line flag would be good to start with, just as a simple way to prototype the feature. |
ProblemConcurrently run multiple commands in parallel via one single command definition. ExampleUsing "scripts": {
"watch": "del dist; npm-run-all --silent --parallel watch:*",
"watch:nodemon": "wait-for-change dist/index.js && delay 0.1 && nodemon dist/index.js",
"watch:tsc": "tsc --watch --preserveWatchOutput",
}, |
For me, parallelized tasks would help speed up my build. Here is a simple case, but in my real-world use-case, I have around 15 modules, forming a complex dependency graph:
In this case, I want the build to happen like:
If a and b build at the same time, that will speed up the build. |
I agree with @jrop's usecase, but I also have e.g. an all recipe, which depends on configure, build, packaging, deploy recipes. Here I need the sequence in order. |
Just a thought, wouldn't something like Make's Seems to be the way to support it that would be consistent with the idea behind the project |
The trick seems to be that sometimes, some will want the tasks to run in series, and sometimes in parallel. It seems to me that some extra syntax would need to be defined for dependencies. Say:
I'm not proposing this as the final syntax, but something like this would be useful in a task runner. |
This is something I'd like to see. I have four recipes that use the same sources but do slightly different things and are independent from one another, so something like |
Of course, it is not an ideal solution but works fine for tasks that don't end until manual termination, such as spinning servers. At my set dotenv-load
default: run-meilisearch watch-jq
run-meilisearch:
setsid alacritty --working-directory=. -e docker run -it -p 7700:7700 -e "MEILI_MASTER_KEY=$MEILISEARCH_MASTER_KEY" -v data-ms:/app/.data-ms getmeili/meilisearch:v0.26.0rc0 &
watch:
~/.cargo/bin/systemfd --no-pid -s http::5001 -- cargo watch -x run -q | jq
watch-jq:
@echo Waiting 5 seconds to ensure meilisearch starts
sleep 5 && setsid alacritty --working-directory=. -e just watch &
release-jq:
~/.cargo/bin/systemfd --no-pid -s http::5001 -- cargo run --release | jq
|
Couldn't you just do... a:
# Long running process
b:
# Long running process
parallel-sh:
just a & # runs in the background so errors (probably?) get ignored by this recipe
just b # runs in the foreground and treated normally regarding errors
parallel-cmd:
start /b just a
just b ...in most cases? My-Machine:best-project-ever account$ just parallel-sh -or- C:\Users\account\Projects\Best-Ever> just parralel-cmd Or is more consistent error handing necessary? |
To add to the use cases, I have daydreams about using just to replace Apache Airflow (a data engineering orchestration tool) |
Adding in my use case for something like this, I have two commands: one to run a vite (JS) dev server, and one command to run a cargo backend web server. I'd like one command that runs both at the same time, and kills them both when I hit Ctrl+C. |
It seems like this is already possible. My
Starts my Hugo server, and at the same time waits 5 seconds, changes directory, and runs npm start The secret is |
Good to know! I see a lot of people using Now, when you run |
Just want to point out that the |
Something similar to the |
When I first adopted For the sequential case,
is merely syntactic sugar for:
which really doesn't add all that much. Conversely, getting Hence, I would argue that I also want to add that in the JS ecosystem, a long time ago, task runners like Grunt and Gulp struggled with basically the same challenge. |
Has anyone taken a look at Taskfile? It both runs dependencies in parallel and supports a command line flag to run the specified tasks in parallel: |
@timdp Definitely agree this is important and one of the biggest missing feature! I actually took a crack at this, but ran into weird lifetime/sync/send issues, and the code was really ugly, so I tabled it, but if someone else wants to take a shot, they definitely could. I created a project that does NFTs on Bitcoin called Ordinals, and it's popping off, so my review bandwidth is extremely limited, just a heads up. |
I created a draft PR to implement this feature, following the pattern from Taskfile (parallel execution of dependencies, parallel task execution when given multiple tasks on the commandline). More work to be done, but depends on answers by maintainers. |
You can get it to run in parallel and stop all processes at the end fairly easily, assuming you're using bash:
The |
Yeah, but then you might as well create a |
btw, while I don't have any answer from any maintainer yes, #1562 already works for the things I wanted to work. Sadly These things would work with my PR: 1. Run the given recipes on the command line in parallel:$ just --parallel recipe_1 recipe_2 recipe_3
[...] 2. using the
|
One workaround working for me if you use full:
tmux new-window 'just server'
tmux new-window 'just worker' |
Now that is a PR I didn't think about for a long time ;) From what I remember, it works for long-running processes, and does interleave the output. A major difference to |
Nice.
This would 'seal the deal' and distinguish |
I'll add one tidbit around this: it'd be awesome if |
I love the '[parallel]' idea to declare tasks that can be parallelized safely. For instance in CI, I usually perform all checks in // ( Something like this chain in a just file could be feasible
a new parameter My main pbl with |
Instead I would prefer that each task is by default independent, so I do not need to write anything extra to run tasks in parallel, and instead there could be an option to mark that some task conflict with another. Because with |
I've been using just with concurrently in the mean time, it's pretty good |
Unfortunately |
Another option might be to introduce additional syntax for dependencies: # dependencies executed sequentially
tasks: task1 task2 task3
# task1 executes, then task body and then task2 and task 3 (already implemented)
# https://just.systems/man/en/chapter_42.html?highlight=middl#running-recipes-at-the-end-of-a-recipe
tasks: task1 && task2 task3
# execute task1 and task2 in parallel, and when task2 finishes continue with task3
tasks: task1 & task2 task3
# execute task1 and task2 and task3 in parallel
tasks: task1 & task2 & task3 So occurrences of |
@W1M0R I do not understand why the dependant should define order of the tasks to be run. This also introduces problem when for example |
If both depend on task 0 then it should run once. In this example, the author of the tasks recipe knows that the individual tasks can be executed in parallel without interfering with each other. There may be other tasks that shouldn't be run in parallel, i.e. one that deletes a folder and another one that creates that folder. The recipe author should get to decide which tasks it wants to have executed in parallel. |
For long running tasks that need to run in parallel, I call into the following Taskfile.yaml: version: '3'
interval: 2s
tasks:
# Also see: https://taskfile.dev/usage/#watch-tasks
dev-templ: just dev-templ
dev-astro: just dev-astro
dev-go: just dev-go
dev:
desc: Run the long-running watches in parallel (Just can't do parallel tasks yet)
deps: [dev-templ, dev-astro, dev-go] The dev-up:
task dev Running |
@W1M0R I also like using Goreman for this. Hopefully this will be possible in just soon. |
Thanks for the tip @yonas |
I wanted to ask whether we could extend
just
that it runs independent dependencies in parallel similar to make. Or is this feature somewhere hidden somewhere?The text was updated successfully, but these errors were encountered: