Testing code starting background tasks in Elixir
After a change my mix test
returned the following error:
20:01:58.722 [error] Postgrex.Protocol (#PID<0.431.0>) disconnected: ** (DBConnection.ConnectionError) owner #PID<0.1071.0> exited
Client #PID<0.1084.0> is still using a connection from owner at location:
# ...
After a bit of recherche I learned what the problem is: my background task tries to use the database connection, but since my test function ended Ecto.Adapters.SQL.Sandbox
adapter already closed the database connection.
The common solution seems to be starting the asynchronous code under a supervisor and then iterate over the started tasks of that supervisor and kill them.
I don't wanted to do this, this has more implications than I want. Most of my background functions are just fire and forget tasks, so I came up with another solution: I encapsulated my Task.start/1
calls to another function which runs the task synchronously in test mode:
defmodule Cforum.Helpers.AsyncHelper do
def run_async(fun) do
if Mix.env() == :test,
do: fun.(),
else: Task.start(fun)
end
end
This just completely avoids that problem.