2009-10-02 8 views
9

Ho un modulo genserver che devo avviare come server in esecuzione in background. Durante lo sviluppo, ho usato un terminale Erl standard per avviarlo comeErlang erl_call causa la chiusura del modulo 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> 

Tutto funzionava bene e sono stato in grado di chiamare il server da altri moduli.

Ora, ho bisogno di eseguirlo come server continuamente e incappato nella funzione erl_call. Così ora faccio:

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

Ma, il server si avvia, ma si spegne automaticamente. Ho abilitato il flag -d per vedere cosa non va. Questo è ciò che vedo nel file di traccia di debug:

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

Qualche idea su cosa sta causando l'arresto automatico del server? La traccia dice anche che il motivo della risoluzione era normale. Ma non ho avviato la rescissione.

risposta

12

erl_call utilizza i rpc funzioni di un nodo erlang per svolgere il proprio lavoro - erl_call -sname Node M F A è lo stesso facendo rpc:call(Node, M, F, A) da un nodo erlang differente collegato a Node.

rpc:call spawn un processo per eseguire il M:F(A) a cui è stato richiesto, così nel tuo caso verrà generato un processo che esegue my_server:start_link() e quindi esce. Poiché my_server è collegato al processo rpc, uscirà quando il processo rpc viene eseguito - il processo rpc è collegato e invia un segnale di uscita al processo my_server. Puoi vederlo nel rapporto errori: Last message in was {'EXIT',<0.59.0>,normal} - questo è il segnale di uscita dal processo rpc che spegne il tuo my_server.

ho il sospetto che si sia desidera chiamare my_server:start(), invece, in modo che il my_server non sarà collegata al processo rpc e sarà sopravvivere al processo rpc in uscita. Meglio ancora, creare un'applicazione OTP, my_app e supervisore di livello superiore, my_sup, che inizia my_server all'avvio del nodo.


Adam fa notare, inoltre, che la funzione terminerà non gestisce il caso terminate(normal, {20499,24596,28693,32790,36887,40984,45081}) e si blocca quando il my_server si sta spegnendo.

5

il server è in uscita perché qualcuno ha detto di farlo, è per questo che si vede questo:

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

Potrebbe provenire dalla gen_server stesso, o inviando un messaggio di uscita ad esso, come questo:

exit(PidOfServer, normal) 

tuo terminate/2 funzione nel vostro gen_server sembra essere difettoso, dal momento che non accetta gli argomenti dati ad esso (se sono validi, che è). Questo è il motivo per cui hai un incidente.

** {function_clause,[{myserver,terminate, 
          [normal, 
          {20499,24596,28693,32790,36887,40984,45081}]}, 
       {gen_server,terminate,6}, 
       {proc_lib,init_p_do_apply,3}]} 
Problemi correlati