Raees678
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.
Trending in Questions
Other Trending 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
- #blog-post
- #phoenix_html
- #iex
- #graphql
- #ai
- #genstage
- #elixirconf-us
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex










First 2 of 2 Posts
josevalim
Check out the docs for async: Task — Elixir v1.13.4
IEx traps exits (so it can report them).
tiagodavi
Hey Jose,
I noticed that the same behavior occurs during a normal Phoenix request. If my request finishes while I have a task running, the task doesn’t terminate along with the request—it continues running afterward. Does this mean the request is trapping exits?
Additionally, I observed during tests that
Task.asyncseems to automatically take ownership of a database connection, whereas a traditionalspawnfunction does not. I’ve been searching through the documentation to confirm this behavior.