Raees678

Raees678

Task spawned with async runs despite caller's exit

I have a two part question concerning a module like so:

defmodule AsyncAwait do
  defp long_running_task(id) do
    Process.sleep(5_000)
    IO.puts("Completed #{id}")
    {:ok, "Completed #{id}"}
  end

  def perform_tasks(task_ids \\ [0, 1, 2]) do
    task_ids
    |> Enum.map(fn id ->
      Task.async(fn ->
        long_running_task(id)
      end)
    end)
    |> Enum.map(fn task ->
      IO.inspect(self())
      Task.await(task, 1_000)
    end)
  end
end

When I launch the iex shell and run AsyncAwait.perform_tasks(), I recieve a timeout and an exit as expected, at the await:

** (exit) exited in: Task.await(%Task{owner: #PID<0.151.0>, pid: #PID<0.153.0>, ref: #Reference<0.3029894714.2600271873.129496>}, 1000)
    ** (EXIT) time out
    (elixir 1.13.4) lib/task.ex:809: Task.await/2
    (elixir 1.13.4) lib/enum.ex:1593: Enum."-map/2-lists^map/1-0-"/2

I would expect that this kills the caller process, and hence also all the associated task processes that were spawned during the async call. This is what the docs say:

A timeout, in milliseconds or :infinity, can be given with a default value of 5000. If the timeout is exceeded, then the caller process will exit. If the task process is linked to the caller process which is the case when a task is started with async, then the task process will also exit. If the task process is trapping exits or not linked to the caller process, then it will continue to run - Task — Elixir v1.13.4

  1. Normally when the caller process exits, I expected it would kill the iex shell since they exist in the same process. I can verify that they exist in the same process since I call IO.inspect(self()) in the anonymous function that executes the Task.await, and when comparing it to the output of calling self() in iex, they are both indeed the same.

However the iex prompt numbers do not reset after the error, and its pid does not change either. Manually killing the current process using Process.exit(self(), :exit) resets the iex prompt number and the pid of the iex process, so I suspect that the caller process is not actually being killed. If it isn’t then what process actually exits due to the timeout?

  1. After 5 seconds I still see the output from the tasks in the iex shell:
Completed 0
Completed 1
Completed 2

This indicates that the async tasks that were spawned are still running.

How could this be happening? Assuming the caller processes did actually exit this means the associated task processes did not exit, which contradict the docs above.

Marked As Solved

josevalim

josevalim

Creator of Elixir

Check out the docs for async: Task — Elixir v1.13.4

IEx traps exits (so it can report them).

Where Next?

Popular in Questions Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
LegitStack
I’m hoping you guys can give me some general advice and perhaps code examples if you’re feeling up to it. I’m very interested in Elixir,...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

Other popular topics Top

Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New

We're in Beta

About us Mission Statement