I recently upgraded my phoenix project to Ecto 2.0.2. I have some code that is using Task.Supervisor.async_nolink
to make some updates to the db on its own thread. I am getting the following error when my tests run (only occurs on my tests)
[error] Postgrex.Protocol (#PID<0.XXX.0>) disconnected: **
(DBConnection.ConnectionError) owner #PID<0.XXX.0> exited while
client #PID<0.XXX.0> is still running with: shutdown
Now I think I understand whats happening: The Ecto Sandbox connection pool is being checked back in before the db transaction is complete. According to the docs (at least the way I read them) the way to get around that stuff is to use a shared connection pool: Ecto.Adapters.SQL.Sandbox.mode(MyApp.Repo, {:shared, self()})
which I am doing. Unfortunately this is not working.
How do I set up my tests so that this error does not occur?
If anyone else encounters this, I got an answer back on this directly from the language author Jose Valim:
I had the same problem today and I think I've found a possible solution with allows the tests to run concurrently.
I'm using the technique described here: http://blog.plataformatec.com.br/2015/10/mocks-and-explicit-contracts/ to replace Task.Supervisor while running tests.
Instead of:
I'm doing:
and then I define
TestTaskSupervisor
and add
config :app, :task_supervisor, TestTaskSupervisor
inconfig/test.exs
.This way, I'm sure that the task will run synchronously and finish before the test process.
This problem is finally solved by Elixir v1.8.0 and
db_connection
v2.0.4. See https://twitter.com/plataformatec/status/1091300824251285504 and https://elixirforum.com/t/problem-asynchronizing-ecto-calls/19796/8If you use versions of Elixir and DBConnection newer than those mentioned above, the test should work out of the box without any errors.