2010-12-03 11 views
5

Ich habe ein Logikmodul, das einem Supervisor den Start von untergeordneten Prozessen anweist. Ich muss diese Kinder pid im Zustand der Logikmodule speichern. Aber ich muss auch ein Kind Pid aktualisieren, wenn der Supervisor es neu startet.Registrieren eines untergeordneten Elements in dem Prozess, der den Aufruf start_child initiierte

So kann ich nicht den Rückgabewert pid von der start_child Anruf verwenden, da das mir nur die pid beim ersten Start, nicht die Neustarts geben wird. Im Moment mache ich den Child-Prozess eine Register-Funktion aufrufen (Update-Status mit neuen PID) im Logikmodul von der Childs-Init-Funktion. Auf diese Weise kann das Logikmodul die pid in ihrem Zustand aktualisieren, wenn ein Prozess neu gestartet wird. Das Logikmodul ist ein gen_server und ich mache eine Umwandlung, wenn ich den Kindprozess registriere.

Kann jemand ein Problem mit diesem sehen und gibt es irgendeinen anderen "richtigen" Weg, es zu tun?

Antwort

6

Ein Problem ist, dass Sie die ChildPid haben und das Kind könnte jetzt tot sein. Wenn Sie eine Nachricht über cast senden, bedeutet dies, dass die Nachricht verloren gegangen ist. Und durch eine call werden Sie sich mit einer {'EXIT', noproc} abstürzen, es sei denn, Sie fangen es aus der call heraus. Ihre Lösung muss berücksichtigen, dass eine Pid in dem Moment, in dem Sie eine Nachricht senden, möglicherweise längst vorbei ist. Normalerweise ignoriert man, dass die Nachricht verloren geht, indem man sich selbst stürzt oder das Problem behebt und dann weitergeht.

Es gibt ein paar Optionen. Dies ist eine lose Liste:

  • Tun Sie, wie Sie es tun. Lass die Kinder sich registrieren.
  • Lassen Sie das Logikmodul eine monitor auf dem Kind haben. Auf diese Weise wissen Sie, ob es stirbt.
  • Verwenden Erlang SolutionsGPROC Module: https://github.com/esl/gproc, die Ihnen eine saubere Schnittstelle zu einer ETS-Tabelle der Verfolgung der Informationen gibt. Beachten Sie, dass Sie eine PID in gproc nachsehen können und erwarten seine Ankunft, wenn der Prozess gerade neu gestartet wird.
  • Verwenden Sie supervisor:which_children, um das relevante Kind zu finden.
  • rollen Sie Ihre eigene ETS-Tabelle als eine Variante der gproc
  • lokaler Namen Atome sein, aber global registriert Namen jeder Begriff sein kann (sie intern in einer ETS-Tabelle gespeichert sind, ein wenig wie GPROC sucht, siehe die global_name_server in kernel/stdlib). Verwenden Sie die globale Struktur, um die betreffenden PIDs zu verfolgen.