- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一组测试需要先启动 GenServer。根据经验,我知道在每次测试后进行清理是一种很好的做法,因此我也想在每次测试后停止 GenServer。
这里的问题是我不知道如何在测试完成后停止 GenServer。我总是遇到一些并发问题。
defmodule MyModuleTest do
use ExUnit.Case
alias MyModule
setup do
MyModule.Server.start_link(nil)
context_info = 1
more_info = 2
%{context_info: context_info, more_info: more_info}
end
describe "some tests" do
test "returns {:ok, order_id} if order was deleted correctly", context do
# do test here that uses created server and passed context
assert actual == expected
#clean up?
end
end
end
现在,我试过了on_exit
/2像下面这样:
setup do
{:ok, server} = MyModule.Server.start_link(nil)
context_info = 1
more_info = 2
on_exit(fn -> GenServer.stop(server) end)
%{context_info: context_info, more_info: more_info}
end
但是我得到这个错误:
** (exit) exited in: GenServer.stop(#PID<0.296.0>, :normal, :infinity)
** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
我觉得这退出得太早了。
我也试过使用 start_supervised
然而,由于我的 GenServer
在 handle_continue
中进行了冗长的初始化,因此测试在服务器准备就绪之前运行。
我该如何解决这个问题?
最佳答案
我终于明白是怎么回事了。
事实证明 start_supervised
正在按预期工作,并且实际上正在等待 GenServer 结束 handle_continue
(好吧,这不是 正是等待,它仍然发送消息并将这些消息放入队列中等待适当的时间执行)。
这里的问题是我没有完全清除我在 handle_continue
中启动的所有内容。事实证明,即使在原始 GenServer 终止后,我启动的一些连接和进程仍然存在。
解决方案有两个:
在代码中,这被翻译成:
def init(_) do
Process.flag(:trap_exit, true) # trap all exits!
{:ok, %{}, {:continue, :setup_queue}}
end
def handle_continue(:setup_queue, state) do
# do heavy lifting
{:noreply, state}
end
def terminate(_reason, state), do:
# undo heavy lifting
有了这个和 start_supervised
在我的 setup
block 中,一切都很好。
关于elixir - 每次测试后停止 GenServer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65630009/
我在自动启动监督树时遇到了死锁问题。一个 GenServer 的初始状态是树中另一个主管的子进程。代码如下: 主管和 worker : defmodule Parallel.Worker.Superv
考虑这样简单的 GenServer 模块: defmodule Crap do use GenServer ... #All the needed crap def handle_info
背景 我有一组测试需要先启动 GenServer。根据经验,我知道在每次测试后进行清理是一种很好的做法,因此我也想在每次测试后停止 GenServer。 问题 这里的问题是我不知道如何在测试完成后停止
在elixir GenServer中,有sync和async方法,handle_cast和handle_call。在异步情况下,如果该方法失败,我如何获得通知? 方法失败意味着在handle_call
我对一些 OTP 概念不熟悉。我有 GenServer,它将向 RabbitMQ 发布事件。此 GenServer 具有状态:amqp Chanel,它在 init() 期间启动一次,并在 cast
我缩小了问题的大小,因为它太大了。这是代码: defmodule MayRaiseGenServer do use GenServer def start_link do IO.put
我正在练习这个例子。 https://github.com/kwmiebach/how-to-elixir-supervisor 我按照说明进行操作并了解它是如何工作的,但我无法理解 Supervis
我的一项服务与速率受限的外部 API 进行通信,因此我想确保每 10 秒发送的调用不超过 1 个。 我的天真的方法是拥有一个长期运行的 API 服务,并在每次调用后超时: def handle_cas
我最近遇到了一点麻烦:GenServer 进程使用的内存非常高,可能是因为大量的二进制泄漏。 问题来自于这里:我们通过 GenServer 接收大型二进制文件,并将它们传递给消费者,然后消费者与该数据
我知道我可以像这样调用 GenServer GenServer.call(pid, request) # using a pid 或者像这样 GenServer.call(registered_nam
我的一项服务与速率受限的外部 API 进行通信,因此我想确保每 10 秒发送的调用不超过 1 个。 我的天真的方法是拥有一个长期运行的 API 服务,并在每次调用后超时: def handle_cas
假设我有 GenServer 实例: defmodule MyModule do use GenServer def init(_) do {:ok, %{}} end #... e
我有一个为单个项目实现功能的 GenServer,例如: def handle_call({:sync, id}, _from, state) do ## update data {:
给定一个简单的 GenServer过程。 defmodule KVServer do use GenServer def start do GenServer.start(__MODU
我正在编写一个模块来查询在线天气 API。我决定将它作为一个应用程序来实现,并带有一个受监督的 GenServer . 这是代码: defmodule Weather do use GenServ
场景: 我有一个简单的GenServer来管理某些状态。 目前,我正在使用 map 来管理我的状态。但它正在增长我正在向该状态添加更多数据。 问题: 那么,为了获得一些编译时保证,我的 GenServ
我正在阅读this关于如何从现有的phoenix应用程序中提取微服务的文章。作者重构了 phoenix 应用程序 Controller 之一,并将其方法之一移至 Genserver,之后将该 Ge
我有一个模拟应用程序范围的 Repo 的测试。大多数时候,测试都是绿色的。当我在循环中运行测试时,使用相同的种子,可能有 10% 的运行成功,但带有 GenServer 终止消息: 15:39:34.
我有一个 GenServer,它负责联系外部资源。调用外部资源的结果并不重要,偶尔失败是可以接受的,所以使用 handle_cast 似乎适用于代码的其他部分。我确实有一个用于该外部资源的类似接口(i
在这两种方法中,我都坚持如何通过给定的一组 id 或组映射进程,然后将存储的结构映射到过滤数据。%{group => [users]}执行。 我意识到组将与用户相反,因此我创建了一个使用组名称作为键的
我是一名优秀的程序员,十分优秀!