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 of5000. 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 withasync, 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
- Normally when the caller process exits, I expected it would kill the
iexshell since they exist in the same process. I can verify that they exist in the same process since I callIO.inspect(self())in the anonymous function that executes theTask.await, and when comparing it to the output of callingself()iniex, 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?
- After 5 seconds I still see the output from the tasks in the
iexshell:
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
Check out the docs for async: Task — Elixir v1.13.4
IEx traps exits (so it can report them).
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








