task icon indicating copy to clipboard operation
task copied to clipboard

Stuck in deadlock with up-to-date "run once" task

Open postlund opened this issue 3 years ago • 3 comments

  • Task version: v3.12.0 (h1:viFy8kdDZ2iTcpTuxzzJCeKtTGt9U+5iXMVIpLjvIro=)
  • Operating System: Linux 5.10.16.3-microsoft-standard-WSL2

Example Taskfile showing the issue

I have a quite large project where I manage to end up in a deadlock every time I try to run task. It seems to be related to a run: once task that other tasks depend on. This happens when I run with -C X where X < 4 in my case. I suspect that If I add more "apps" I will eventually end up in this situation when running with all my cores as well.

I've managed to condense my layout into this:

version: "3"

tasks:
  do_something:
    run: once
    status:
      - "true"

  prepare_env:
    cmds:
      - task: do_something

  app1:
    deps: [prepare_env]

  app2:
    deps: [prepare_env]

  default:
    deps: [app1, app2]

Running this example ends up in deadlock about one in ten times I run it (my larger repo ends up in deadlock every time, as I mentioned). I'm pretty sure it has to do with timing.

Example of a successful run:

$ ../work/task -v -C 1
task: "default" started
task: "app2" started
task: "app1" started
task: "prepare_env" started
task: "prepare_env" started
task: "do_something" started
task: status command true exited zero
task: Task "do_something" is up to date
task: skipping execution of task: do_something
task: "prepare_env" finished
task: "prepare_env" finished
task: "app2" finished
task: "app1" finished
task: "default" finished

And with deadlock:

$ ../work/task -v -C 1
task: "default" started
task: "app1" started
task: "app2" started
task: "prepare_env" started
task: "prepare_env" started
task: "do_something" started
task: skipping execution of task: do_something

postlund avatar May 05 '22 04:05 postlund

When you say deadlock, you mean task is sitting there trying to do something, but nothing is happening?

ghostsquad avatar May 05 '22 07:05 ghostsquad

Something like that, yes. In the second run above, it just sits there forever and nothing happens.

postlund avatar May 05 '22 07:05 postlund

+1, seeing this as well on Linux in version v3.13.0.

Workaround for me seems to be to avoid using run: once to be able to use the -C option.

ahus1 avatar Jun 29 '22 07:06 ahus1

I believe I've found the deadlock.

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.

theunrepentantgeek avatar Feb 27 '23 01:02 theunrepentantgeek