我有一个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}]}
知道是什么导致服务器自动关闭吗?跟踪甚至说终止的原因是正常的。但我没有开始终止。
答案 0 :(得分:12)
erl_call
使用erlang节点上的rpc
函数来完成其工作 - erl_call -sname Node M F A
与从{{1}连接的另一个erlang节点执行rpc:call(Node, M, F, A)
相同}}
Node
会生成一个执行您要求的rpc:call
进程,因此在您的情况下,它会生成一个执行M:F(A)
然后退出的进程。因为my_server:start_link()
链接到rpc进程,所以当rpc进程执行时它将退出 - my_server
进程链接到rpc
进程并向其发送退出信号。您可以在错误报告中看到它:my_server
- 这是关闭Last message in was {'EXIT',<0.59.0>,normal}
的{{1}}进程的退出信号。
我怀疑您要么致电rpc
,以便my_server
不会与my_server:start()
进程相关联,并且会在退出my_server
进程后继续存在。更好的是,创建一个OTP应用程序rpc
和顶级管理程序rpc
,它在节点启动时启动my_app
。
Adam还指出你的终止函数不处理my_sup
情况,并在my_server
关闭时崩溃。
答案 1 :(得分:5)
服务器正在退出,因为有人告诉它这样做,这就是你看到这个的原因:
Last message in was {'EXIT',<0.59.0>,normal}
它可能来自gen_server本身,或者通过向它发送退出消息,如下所示:
exit(PidOfServer, normal)
你的gen_server中的terminate/2
函数似乎有问题,因为它不接受给它的参数(如果它们是有效的,那就是)。这就是你崩溃的原因。
** {function_clause,[{myserver,terminate,
[normal,
{20499,24596,28693,32790,36887,40984,45081}]},
{gen_server,terminate,6},
{proc_lib,init_p_do_apply,3}]}