如何在脚本中运行Elixir Supervisor

问题描述 投票:6回答:2

我有一个混合项目,其中包含尽可能简单的Supervisor和GenServer。当我从iex致电时:

EchoCmd.Supervisor.start_link([:Hello])
GenServer.call(:echoserver, :echo)
GenServer.call(:echoserver, :mumble)
GenServer.call(:echoserver, :echo)

:mumble调用引发异常,然后重新启动GenServer,第二个:echo调用正常。

如果我以任何其他方式运行代码,Supervisor将无法重新启动GenServer。例如,我使用以下主要模块创建项目的脚本:

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

:mumble调用引发异常,并且escript终止而无需主管重新启动GenServer。

我没有包括Supervisor和Server模块代码,因为从iex调用时它们可以正常工作,所以我猜这里不需要它们。

我在概念上有误解吗?这是不可能的,还是我做错了?

otp elixir erlang-supervisor gen-server mix
2个回答
5
投票

问题不在于服务器和主管,而在于您调用它们的方式。如果在另一个进程正在等待对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

iex中起作用的原因是iex捕获了出口并允许您键入另一行。


3
投票

脚本行为正确。您只是错过了iex shell如何“帮助您”。

您在代码中所做的事情正在启动linked进程,而不是将其崩溃。并且由于它是一个链接的进程,因此当它出现故障时,它应该关闭所有链接的进程。可能会有一些“例外”,但是您的脚本过程正在发生什么。

外壳程序管理器和过程管理器都可以处理这样的“我死了,你也应该死”的消息。他们通过更改流程(链接流程,而不是濒临死亡的流程)处理此类消息的方式来做到这一点。它允许他们将它们作为普通消息接收(如果需要,可以在receive子句中接收),而不是特殊的内部消息。要更改此行为,请使用Process.flag( :trap_exit, :true)elixir doc指向eralng's one)。它允许外壳程序仅打印已终止进程的死亡,而不是每次执行不良操作时都会死亡。

所以您可以做同样的事情。更改此标志,并且如果您不希望在此类消息的receive中进行模式匹配。但我认为这不是您想要的。由于您的过程是单例的,并且主管会全部重新启动,因此您实际上没有任何理由首先链接到它。无需更新有关死亡和重启的信息,只需让主管担心。就像乔·阿姆斯特朗(Joe Armstrong)所说(可能是措辞)

您无需知道如何修理自动售货机即可使用它。

所以,只是start,而不是start_link

就是说,您可能考虑与超级用户创建链接,超级链接在重启过多后也可能会消失(可能会告诉他以这种方式运行)。它使您可以在死时采取他(和受监督的程序)。或者他可以链接到您的主管或应用程序主管,或以其他方式链接。这取决于您的域,并且没有错误的决定,您只需要检查对您有用的。这是设计决定,您必须尝试或阅读有关它的更多信息:

http://elixir-lang.org/getting_started/mix_otp/5.html

http://www.erlang.org/doc/design_principles/des_princ.html

http://learnyousomeerlang.com/supervisors

© www.soinside.com 2019 - 2024. All rights reserved.