2010-12-03 32 views
5

J'ai un module logique qui indique à un superviseur de démarrer les processus enfants. J'ai besoin de stocker le pid de ces enfants dans l'état des modules logiques. Mais j'ai aussi besoin de mettre à jour un pid childs si le superviseur le redémarre.Enregistrement d'un enfant dans le processus à l'origine de l'appel start_child

Je ne peux donc pas utiliser la valeur de retour pid de l'appel start_child, car cela ne me donne que le pid au premier démarrage, pas les redémarrages. En ce moment, je fais en sorte que le processus fils appelle une fonction de registre (met à jour l'état avec un nouveau pid) dans le module logique à partir de la fonction init de childs. De cette façon, le module logique peut mettre à jour le PID dans son état chaque fois qu'un processus est redémarré. Le module logique est un gen_server et je fais une distribution quand j'inscris le processus fils.

Quelqu'un peut-il voir un problème avec cela et y a-t-il une autre façon plus «correcte» de le faire?

Répondre

6

Un problème est que vous avez le ChildPid et que l'enfant est peut-être mort maintenant. L'envoi d'un message via un cast signifie que le message est perdu. Et à travers un call vous vous écraserez avec un {'EXIT', noproc} sauf si vous l'attrapez sur le call. Votre solution doit prendre en compte le fait qu'un Pid peut être parti depuis l'instant où vous envoyez un message. Habituellement, en ignorant que le message est perdu, en vous écrasant ou en remédiant au problème, puis continuez.

Il existe plusieurs options. Ceci est une liste libre:

  • Faites comme vous. Laissez les enfants s'enregistrer eux-mêmes.
  • Laissez le module logique avoir un monitor sur l'enfant. De cette façon, vous savez si elle meurt.
  • Utilisez Erlang Solutionsgproc Module: https://github.com/esl/gproc qui vous donne une interface propre à une piste de maintien de la table ETS de l'information. Notez que vous pouvez rechercher un pid dans gproc et attendre son arrivée si le processus ne fait que redémarrer. Utilisez supervisor:which_children pour trouver l'enfant correspondant.
  • Réaliser votre propre table ETS comme une variante de gproc
  • locaux noms doivent être des atomes, mais les noms enregistrés dans le monde peuvent être un terme (ils sont stockés en interne dans une table ETS regardant un peu comme celui de gproc, voir le global_name_server dans kernel/stdlib). Utilisez la structure globale pour suivre les pids en question.