我在GenServer
玩了一下,我在实施自定义init
回调时遇到了问题。
请考虑以下代码:
defmodule GenS do
use GenServer
def start_link(initial \\ 0) do
GenServer.start_link(__MODULE__, initial)
end
def init(initial) do
case initial do
3 -> {:stop, "Can't initialise with 3"}
_ -> {:ok, initial}
end
end
end
case GenS.start_link(3) do
{:error, reason} -> IO.puts "Failed with #{reason}"
{:ok, _} -> IO.puts "This has worked!"
end
IO.puts "I'm still alive!"
执行此代码时,我可以看到输出:
▶ elixir gens.ex
** (EXIT from #PID<0.46.0>) "Can't initialise with 3"
虽然我期待成功分支的类似输出(当作为参数传递的值不同于3
时):
▶ elixir gens.ex
This has worked!
I'm still alive!
根据GenServer.start_link/3
的文件:
如果
init/1
回调因原因而失败,则此函数返回{:error, reason}
。否则,如果它返回{:stop, reason}
或:ignore
,则该过程将终止,此函数将分别返回{:error, reason}
或:ignore
。
我希望能够返回元组,我可以啪嗒啪嗒地响起,但似乎并非如此。你有什么建议吗?
答案 0 :(得分:1)
我希望能够返回元组,我可以啪的一声,但看起来并非如此。你有什么建议吗?
这里的问题是你正在链接到生成的进程,并且从{:stop, ...}
返回init
正在向调用进程发送一个退出信号,默认情况下会终止该调用进程。
您可以切换到使用GenServer.start
(如果愿意,可以稍后手动链接进程),或者在开始GenS
之前运行以下命令来捕获退出信号:
Process.flag(:trap_exit, true)
(请注意,当GenS
死亡时,这会向调用进程发送一条消息,您可能要放弃该消息以防止浪费内存。)
在这两种情况下,我都得到以下输出:
Failed with Can't initialise with 3
I'm still alive!