2009-10-02 19 views
9

Tengo un módulo genserver que necesito iniciar como un servidor ejecutándose en segundo plano. Durante el desarrollo, he usado un terminal ERL estándar para iniciarlo comoErlang erl_call hace que el módulo gen_server se cierre

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

Todo funcionaba bien y era capaz de llamar al servidor desde otros módulos.

Ahora, necesito ejecutarlo como un servidor continuamente y tropecé con la función erl_call. Así que ahora lo hago:

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

Pero, el servidor se inicia, pero se apaga automáticamente. He habilitado el indicador -d para ver qué está pasando mal. Esto es lo que veo en el archivo de rastreo de depuración:

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

Alguna idea de lo que está haciendo que el servidor se apague automáticamente? La huella incluso dice que el motivo de la terminación fue normal. Pero no inicié la terminación.

Respuesta

12

erl_call utiliza las funciones rpc en un nodo Erlang para hacer su trabajo - erl_call -sname Node M F A es lo mismo que hacer rpc:call(Node, M, F, A) desde un nodo Erlang diferente conectado a Node.

rpc:call genera un proceso para ejecutar el M:F(A) que usted solicitó, por lo que en su caso generará un proceso que ejecuta my_server:start_link() y luego sale. Como my_server está vinculado al proceso rpc, saldrá cuando lo haga el proceso rpc - el proceso rpc está vinculado y envía una señal de salida al proceso my_server. Puede verlo en el informe de error: Last message in was {'EXIT',<0.59.0>,normal} - esa es la señal de salida del proceso rpc que apaga su my_server.

sospecho que o bien desea llamar my_server:start() lugar, por lo que el my_server no estará relacionado con el proceso de rpc y va a sobrevivir el proceso rpc salir. Mejor aún, crea una aplicación OTP, my_app, y supervisor de nivel superior, my_sup, que inicia my_server cuando se inicia el nodo.


Adam señala también que la función de terminar no maneja el caso terminate(normal, {20499,24596,28693,32790,36887,40984,45081}) y se bloquea cuando la my_server se está cerrando.

5

El servidor está saliendo porque alguien le dijo que lo haga, es por eso que se ve esto:

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

Podría haber venido de la propia gen_server, o enviando un mensaje de salida a la misma, así:

exit(PidOfServer, normal) 

su función terminate/2 en su gen_server parece ser defectuoso, ya que no acepta los argumentos dados a él (si son válidos, se entiende). Es por eso que tienes un accidente.

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