10 *_*cls 6 elixir-mix elixir erlang-otp gen-server erlang-supervisor
我有一个混合项目,尽可能简单的Supervisor和GenServer.当我从iex打电话时:
EchoCmd.Supervisor.start_link([:Hello])
GenServer.call(:echoserver, :echo)
GenServer.call(:echoserver, :mumble)
GenServer.call(:echoserver, :echo)
Run Code Online (Sandbox Code Playgroud)
:mumble调用引发异常,然后GenServer重新启动,第二个:echo调用正常.
如果我以任何其他方式运行代码,Supervisor将无法重新启动GenServer.例如,我使用主模块创建项目的escript,如下所示:
defmodule EchoCmd.Echo do
def main(args) do
EchoCmd.Supervisor.start_link([:Hello])
GenServer.call(:echoserver, :echo)
GenServer.call(:echoserver, :mumble)
GenServer.call(:echoserver, :echo)
end
end
Run Code Online (Sandbox Code Playgroud)
:mumble调用引发异常,escript终止,而Supervisor没有重启GenServer.
我没有包含Supervisor和Server模块代码,因为它们在从iex调用时工作正常,所以我猜这里不需要它们.
我有一个概念上的误解吗?这不可能,或者我做错了什么?
问题不在于您的服务器和主管,而在于您调用它们的方式.如果服务器在另一个进程正在等待回复时GenServer.call退出,则调用进程也会退出,因此最后一次调用永远不会发生.原因是如果同步调用失败(GenServer.call同步而不是GenServer.cast),进程不可能继续处于无效状态.如果您这样做只是为了测试主管,那么您可以尝试:
defmodule EchoCmd.Echo do
def main(args) do
EchoCmd.Supervisor.start_link([:Hello])
GenServer.cast(:echoserver, :echo)
GenServer.cast(:echoserver, :mumble)
GenServer.cast(:echoserver, :echo)
end
end
Run Code Online (Sandbox Code Playgroud)
它的工作原理iex是iex捕获出口并允许您键入另一行.