这是一个有点奇怪的问题。我们正在编写一个长生不老药应用程序,它将测试不同应用程序的各种基础设施。
从本质上讲,我想做但无法做的是模拟 redis 连接错误并能够从该错误中恢复。 由于 Redix 和 Exredis 似乎都从新的连接 pid 中引发了错误,因此我实际上无法做任何事情。
我们本质上需要的示例:
def is_redis_down() do
{:ok, conn} = Redix.start_link("redis://wrong", name: :redix)
case Redix.command(conn, ["ping"]) do
{:ok, response} ->
Redix.stop(conn)
response !== "PONG"
{:error, _ } ->
GenServer.stop(conn, :normal)
true
end
end
问题是,如果将连接字符串保留为错误,start_link返回 Pid,但 case 语句永远不会运行。 就像start_link使父 pid 崩溃一样。 关于如何恢复的任何想法? 如果它连接并发送 ping,我只想要一个 true,如果连接失败,我只想要一个 false。
我尝试在任务和单独的 pid 中嵌套。
Redix有一个sync_connect
选项。如果将其设置为 true,则函数将在链接建立后返回,如果出现错误,则崩溃。您可以使用Process.flag(:trap_exit, true)
来捕获退出消息,以防止父进程崩溃。之后,您只需要检查{:ok, conn}
和{:error, error}
:
defmodule A do
def is_redis_down() do
Process.flag(:trap_exit, true)
case Redix.start_link("redis://wrong", sync_connect: true) do
{:ok, _} -> true
{:error, _} -> false
end
end
end
IO.inspect A.is_redis_down()
如果您不想更改父进程的trap_exit
,则可以生成一个未链接的Task
并在其中执行此计算。