Erlang erl_call 导致 gen_server 模块退出

标签 erlang

我有一个 genserver 模块,我需要将其作为在后台运行的服务器启动。在开发过程中,我使用标准的 erl 终端来启动它

$erl
Erlang R13B01 (erts-5.7.2) [source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.2  (abort with ^G)
1> myserver:start_link().
<ok, some_pid>

一切正常,我可以从其他模块调用服务器。

现在,我需要将它作为服务器连续运行,并偶然发现了 erl_call 函数。所以现在我这样做:
erl_call -d -s -a 'myserver start_link' -sname myserver_node

但是,服务器启动,但自动关闭。我启用了 -d 标志以查看发生了什么问题。这是我在调试跟踪文件中看到的:
===== Log started ======
Fri Oct  2 04:42:32 2009

erl_call: sh -c exec erl -noinput -sname myserver_node -s erl_reply reply 174.143.175.70 42457 5882

=ERROR REPORT==== 2-Oct-2009::04:44:05 ===
** Generic server myserver terminating
** Last message in was {'EXIT',<0.59.0>,normal}
** When Server state == {20499,24596,28693,32790,36887,40984,45081}
** Reason for termination ==
** {function_clause,[{myserver,terminate,
                               [normal,
                                {20499,24596,28693,32790,36887,40984,45081}]},
                     {gen_server,terminate,6},
                     {proc_lib,init_p_do_apply,3}]}

知道是什么导致服务器自动关闭吗?跟踪甚至说终止的原因是正常的。但我没有发起终止。

最佳答案

erl_call 在 erlang 节点上使用 rpc 函数来完成其工作 - erl_call -sname Node M F A 与从连接到 rpc:call(Node, M, F, A) 的不同 erlang 节点执行 Node 相同。
rpc:call 生成一个进程来执行您要求它执行的 M:F(A),因此在您的情况下,它将生成一个执行 my_server:start_link() 然后退出的进程。因为 my_server 链接到 rpc 进程,所以它会在 rpc 进程完成时退出 - rpc 进程链接到 my_server 进程并向其发送退出信号。您可以在错误报告中看到它: Last message in was {'EXIT',<0.59.0>,normal} - 这是来自 rpc 进程的退出信号,它会关闭您的 my_server

我怀疑您要么想调用 my_server:start() ,以便 my_server 不会链接到 rpc 进程并且将在 rpc 进程退出后继续存在。更好的是,创建一个 OTP 应用程序 my_app 和顶级主管 my_sup ,它在节点启动时启动 my_server

Adam 还指出,您的终止函数无法处理 terminate(normal, {20499,24596,28693,32790,36887,40984,45081}) 情况,并在 my_server 关闭时崩溃。

关于Erlang erl_call 导致 gen_server 模块退出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1508049/

相关文章:

erlang - 为什么 rebar 使用我的 erl_opts 来编译我的 deps?

scala - 从 rpc 调用到其他节点的错误?

erlang - 使用 binary_to_existing_atom(二进制,编码)

erlang - Erlang是约束逻辑编程语言吗?

Erlang 错误处理, 'try' 中的 X 不安全

erlang - Elixir 中的 Code.compile_string 和 Code.eval

ubuntu - 如何在 Ubuntu 18/19 上升级 Elixir 版本

haskell - 是否有像 `dbg` 这样的跟踪调试器可用于 Haskell 或 OCaml?

erlang 元组列表到文本文件中的 map

erlang - EUnit 的assertMatch 中存在多个子句?