我最近将我的 phoenix 项目升级到了 Ecto 2.0.2。我有一些代码正在使用 Task.Supervisor.async_nolink
在自己的线程上对数据库进行一些更新。我的测试运行时出现以下错误(仅发生在我的测试中)
[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
现在我想我明白发生了什么:在 db 事务完成之前,Ecto Sandbox 连接池正在被检入。根据文档(至少是我阅读它们的方式)解决这些问题的方法是使用共享连接池:
Ecto.Adapters.SQL.Sandbox.mode(MyApp.Repo, {:shared, self()})
我正在做的。不幸的是,这不起作用。如何设置我的测试,以免发生此错误?
最佳答案
如果其他人遇到这个问题,我会直接从语言作者 Jose Valim 那里得到答案:
Yes, your understanding of the issue is correct. It is happening because the test process, the one who owns the connection, has exited but the Task is still using its connection. Using {:shared, self()} does not fix it because the test is still owning the connection, you are just sharing it implicitly.
The way to fix is to guarantee the Task has finished before the test exits. This can be done by calling Process.exit(task_pid, :kill). If you don't know the Task PID, you can call Task.Supervisor.which_children(NameOfYourTaskSupervisor) to return all PIDs which you then traverse and kill them. However, if you do this approach, the test cannot run concurrently (as you may kill tasks started by another test).
关于elixir - 测试中的 Ecto 2.0 SQL 沙箱错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38335635/