问题标签 [postgrex]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
101 浏览

elixir - 从同一进程中清理 ExUnit(与 on_exit 不同)

在我们的代码库中,我们有很多涉及与数据库交互的测试(通过Postgrex)。我们有一些 shared ExUnit.CaseTemplates,它们的setup钩子准备 Ecto 沙箱等,这很好用。

我遇到的问题是,当测试进程退出时,我们的测试产生的进程可能仍在与数据库通信,因此我们在日志中得到如下所示的错误:

09:56:51.517 [error] Postgrex.Protocol (#PID<0.2127.0>) disconnected: ** (DBConnection.ConnectionError) owner #PID<0.11626.0> exited

(这里的“所有者”PID 是测试进程,它当然在其设置中产生了数据库连接。)

我尝试过的事情:

  • 在 sharedsetup挂钩中,添加on_exit/2将清理数据库进程的处理程序。

    • 不解决问题。因为在测试进程终止on_exit运行在一个单独的进程中,所以这里可能出现 5% 的竞争条件:Postgrex 可以在处理程序有机会完成其工作之前尝试与现已终止的测试进程通信。on_exit
  • 作为每个测试的最后一行,显式调用共享清理函数以等待数据库事务完成。

    • 这行得通,但是当你有数百个测试时,它很麻烦,而且很容易忘记(在开发和 PR 审查中)。因此,它一直是我们测试不稳定的来源。
    • 更糟糕的是,由于错误消息与测试异步发生,因此很难跟踪哪个测试缺少清理——在有问题的测试完成后的某个时间你会收到错误,但谁知道多久之后!
  • 将ExUnit 源test中的宏复制并粘贴到我们的共享测试代码中,其中一项更改是将对我们的清理函数的调用附加到测试主体的末尾。

    • 这也有效,但它也很笨重,因为我们必须替换每次使用testwithmy_test或其他任何东西,并且我们将被困在维护 copypasta 中。
    • 为了弹性,我们可以将整个测试主体包装在一个try/catch块中并调用清理函数,而不管测试过程如何退出。

我从Elixir 核心邮件列表中的探索中收集到,在之前on_exit/2存在的情况下,曾经有一个teardown在测试过程结束时同步运行的钩子。我真的很感激任何可以模仿这种功能的解决方案。

编辑添加:这是我们共享的示例ExUnit.CaseTemplate

0 投票
0 回答
25 浏览

elixir - 在(用户)空闲超时后设置 DBConnection 进程的自动终止

我的应用程序正在动态创建 Postgrex/DBConnection 池,每个用户一个。最终,我希望连接池在指定的空闲时间后自动终止,因为用户在没有明确注销的情况下来来去去。

我查看了 poolboy 和 DBConnection 的文档,但没有找到任何有用的东西。

我错过了什么还是我只需要自己实现一个空闲跟踪机制?

预先感谢。