2009-10-02 45 views
9

我有一个genserver模块,我需要作为在后台运行的服务器启动。在开发过程中,我用了一个标准ERL终端启动它Erlang erl_call导致gen_server模块退出

$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}]} 

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

回答

12

erl_call使用一个Erlang节点上的功能rpc做它的工作 - erl_call -sname Node M F A相同从连接到Node不同的erlang节点做rpc:call(Node, M, F, A)

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


亚当指出,也当my_server正在关闭您的终止函数不处理terminate(normal, {20499,24596,28693,32790,36887,40984,45081})情况和崩溃。

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}]}