2009-10-02 6 views
9

J'ai un module de serveur que j'ai besoin de démarrer en tant que serveur fonctionnant en arrière-plan. Au cours du développement, j'ai utilisé un terminal standard ERL pour commencer commeErlang erl_call provoque la fermeture du module 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> 

Tout fonctionnait bien et j'ai pu appeler le serveur à partir d'autres modules. Maintenant, j'ai besoin de l'exécuter en tant que serveur en continu et trébuché sur la fonction erl_call. Donc maintenant je fais:

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

Mais, le serveur démarre, mais s'arrête automatiquement. J'ai activé le drapeau -d pour voir ce qui ne va pas. C'est ce que je vois dans le fichier de trace de débogage:

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

Une idée de ce qui provoque l'arrêt automatique du serveur? La trace dit même que la raison de l'interruption était normale. Mais je n'ai pas initié la résiliation.

Répondre

12

erl_call utilise les fonctions rpc sur un noeud Erlang pour faire son travail - erl_call -sname Node M F A est la même chose que faire rpc:call(Node, M, F, A) à partir d'un noeud Erlang différent connecté à Node.

rpc:call génère un processus pour exécuter le M:F(A) que vous lui demandez, donc dans votre cas, il engendrera un processus qui exécute my_server:start_link() puis sort. Parce que my_server est lié au processus rpc, il quittera lorsque le processus rpc fait - le processus rpc est lié à et envoie un signal de sortie au processus my_server. Vous pouvez le voir dans le rapport d'erreurs: Last message in was {'EXIT',<0.59.0>,normal} - c'est le signal de sortie du processus rpc qui ferme votre my_server.

Je soupçonne que vous voulez, soit appeler à la place my_server:start(), de sorte que le my_server ne sera pas lié au processus rpc et survivrez le processus rpc sortant. Mieux encore, créez une application OTP, my_app, et le superviseur de niveau supérieur, my_sup, qui démarre my_server lorsque le nœud démarre.


points de Adam sur que votre fin fonction ne gère pas le cas terminate(normal, {20499,24596,28693,32790,36887,40984,45081}) et se bloque lorsque l'my_server est en train de fermer.

5

Le serveur est sortie parce que quelqu'un a dit à le faire, c'est pourquoi vous voyez ceci:

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

Il aurait pu venir du gen_server lui-même, ou en envoyant un message de sortie, comme ceci:

exit(PidOfServer, normal) 

votre terminate/2 fonction dans votre gen_server semble être défectueux, car il n'accepte pas les arguments qui lui sont données (si elles sont valides, c'est). C'est pourquoi vous avez un accident.

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