Release execution slot while waiting for task #1025
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When the second execution of a Task needs to be skipped because it has already run (or is currently running), the code holds onto an execution slot while it waits for the first execution of the task to complete.
If the first execution of the task has already completed, this wait immediately completes, and the execution slot is also immediately freed.
If the first execution of the task is running its dependencies, it has temporarily released its execution slot to allow the dependencies to be run. Once those are complete, it attempts to reacquire an execution slot before running the commands for the task.
If there is only one execution slot, this gets blocked because the only slot is held by the second execution of the task.
Closes #715
Reproducing
Reproducing this deadlock wasn't too bad thanks to the sample Taskfile provided in #715.
Task
repo./deadlock
with a Taskfile.yaml as described in Stuck in deadlock with up-to-date "run once" task #715Running against
master
, deadlock will usually happen within the first dozen or so invocations.Running against this branch, all 1000 iterations run cleanly.
Detailed analysis.
Normal case
Here's the normal case, when the first execution of the task (prefixed by
[EXEC]
) completes before the second execution (prefixed by[SKIP]
).Deadlock case
Here's the deadlock case, where the second execution of task A commences while the first execution is handling dependencies.