gen_server nommé timer_server a empêché le retour des fonctions du module de minuterie
Question
J'ai créé un superviseur qui a engendré un gen_server
appelant timer_server
. L’une des tâches de ce timer_serve
r consiste à gérer l’enregistrement et à appeler timer:send_interval
pour envoyer un message à un pid à un certain intervalle.
Cependant, dans l'init de la record_timer_server
, où j'appelle timer:start()
, j'obtenais un blocage. La documentation indiquait la minuterie: les fonctions sont immédiatement rétablies, ce qui était très troublant.
Lorsque j'ai renommé send_interval
mon <=> problème, ce problème est résolu. Ma question est alors double:
- Pourquoi est-ce que je pourrais créer un processus enregistré <=> s'il en existait déjà lorsque <=> a été appelé par le démarrage de mon application?
- Une fois démarrée, pourquoi cette fonction ne causerait-elle pas un match en quête du nom, si elle appelait mon <=> en utilisant la <=> fonction?
Je ne pense pas que le code soit nécessaire, mais je peux mettre à jour pour en ajouter, si nécessaire.
La solution
Ceci peut être recréé simplement en procédant de la manière suivante, qui se bloque lors de l'appel à timer: send_interval.
1> register(timer_server, self()).
true
2> timer:send_interval(5000, self(), hello).
Tant que cela échoue ...
1> timer:send_interval(5000, self(), hello).
{ok,{interval,#Ref<0.0.0.32>}}
2> register(timer_server, self()).
** exited: {badarg,[{erlang,register,[timer_server,<0.30.0>]},
Il semble donc que le premier appel à timer tente de démarrer un processus appelé timer_server et se bloque si vous avez pris ce nom en premier.
La raison pour laquelle timer est suspendu est le suivant:
ensure_started() ->
case whereis(timer_server) of
undefined ->
C = {timer_server, {?MODULE, start_link, []}, permanent, 1000,
worker, [?MODULE]}
supervisor:start_child(kernel_safe_sup, C), % kernel_safe_sup
ok;
_ -> ok
end.
qui retourne bien, suivi d'un gen_server: appel à timer_server. Votre processus reste bloqué dans l'attente d'une réponse.