gpt4 book ai didi

elixir - 每次测试后停止 GenServer

转载 作者:行者123 更新时间:2023-12-04 17:21:56 26 4
gpt4 key购买 nike

背景

我有一组测试需要先启动 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然而,由于我的 GenServerhandle_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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com