Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erlang erl_call causes gen_server module to quit

Tags:

erlang

I have a genserver module which I need to start as a server running in the background. During development, I used a standard erl terminal to start it as

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

Everything worked fine and I was able to call the server from other modules.

Now, I need to run it as a server continuously and stumbled upon the erl_call function. So now I do:

erl_call -d -s -a 'myserver start_link' -sname myserver_node

But, the server starts, but shuts down automatically. I enabled the -d flag to see what's going wrong. This is what I see in the debug trace file:

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

Any idea what's causing the server to shut down automatically? The trace even says the reason for termination was normal. But I didn't initiate the termination.

like image 516
ErJab Avatar asked Oct 02 '09 06:10

ErJab


2 Answers

erl_call uses the rpc functions on an erlang node to do its work - erl_call -sname Node M F A is the same as doing rpc:call(Node, M, F, A) from a different erlang node connected to Node.

rpc:call spawns a process to execute the M:F(A) that you asked it to, so in your case it will spawn a process that executes my_server:start_link() and then exits. Because my_server is linked to the rpc process, it will exit when the rpc process does - the rpc process is linked to and sends an exit signal to the my_server process. You can see it in the error report: Last message in was {'EXIT',<0.59.0>,normal} - that's the exit signal from the rpc process that shuts down your my_server.

I suspect that you either want to call my_server:start() instead, so that the my_server won't be linked to the rpc process and will survive the rpc process exiting. Better yet, create an OTP application, my_app, and top level supervisor, my_sup, that starts my_server when the node starts.


Adam points out also that your terminate function doesn't handle the terminate(normal, {20499,24596,28693,32790,36887,40984,45081}) case and crashes when the my_server is shutting down.

like image 99
archaelus Avatar answered Oct 23 '22 18:10

archaelus


The server is exiting because someone told it to do so, that's why you see this:

Last message in was {'EXIT',<0.59.0>,normal}

It could have come from the gen_server itself, or by sending an exit message to it, like this:

exit(PidOfServer, normal)

Your terminate/2 function in your gen_server seems to be faulty, since it does not accept the arguments given to it (if they are valid, that is). This is why you get a crash.

** {function_clause,[{myserver,terminate,
                           [normal,
                            {20499,24596,28693,32790,36887,40984,45081}]},
                 {gen_server,terminate,6},
                 {proc_lib,init_p_do_apply,3}]}
like image 5
Adam Lindberg Avatar answered Oct 23 '22 19:10

Adam Lindberg