2016-09-21 4 views
3

Elixirs Mix and OTP Guide Chapter GenServer erläutert, wie Sie einen Registrierungsserver implementieren, der Agenten unter Verwendung von GenServer verwendet.Warum sollte bei der Implementierung eines GenServers besser auf #Referenz als auf #PID geachtet werden?

Die PID jedes Agenten wird in einer Zuordnung gespeichert, wobei die Schlüssel die von den Clients angegebenen Agentennamen sind und die Werte die PIDs des Agenten sind.

Um zu vermeiden, Hinweise auf tote Agenten zu halten, schlägt die Führung neu erstellten Agenten Überwachung Process.monitor/1 mit und leicht den Zustand zu modifizieren, indem eine neue Karte hinzufügen, genannt refs, enthalten Verweise (Werte zurückgegeben durch Process.monitor/1) als Schlüssel und Agenten Namen als Werte. Es zeigt auch, wie mit Überwachungsnachrichten unter Verwendung von handle_info/2 zum Aktualisieren refs umzugehen.

Process.monitor/1 empfängt eine PID (z. B. #PID<0.66.0>) als Parameter und gibt eine Referenz zurück (z. B. #Reference<0.0.0.551>). Die :DOWN Nachricht, die von handle_info/2 abgefangen wird, stellt sowohl die PID als auch die Referenz bereit.

Da wir die ganze Zeit beide Werte kennen: Was sind die Vorteile der Verwendung von Referenzen als Schlüssel über die Verwendung von PIDs in refs, falls vorhanden?

Antwort

2

Dies ist eine Frage der Konsistenz. Während Sie nur Prozesse überwacht haben, gibt es keinen Unterschied. Aber zugrunde liegende :erlang.monitor/2 kann nicht überwachen nur Prozesse: Es gibt Ports usw., die im Grunde keine PID haben.

Vom doc:

Object

Die überwachten Einheit, die das Ereignis ausgelöst hat. Wenn Sie einen lokalen Prozess oder Port überwachen, entspricht Object dem pid() oder port(), der überwacht wurde. Bei der Überwachung des Prozesses oder Ports nach Namen hat Object das Format {RegisteredName, Node}, wobei RegisteredName der Name ist, der mit monitor/2 Aufruf verwendet wurde und Node lokaler oder entfernter Knotenname ist (für Ports, die mit Namen überwacht werden, ist Node immer lokaler Knotenname).

Die Zusammenfassung: Reference ist eine Entität, die überwacht wird. Es könnte ein Prozess sein, ein Port, was auch immer. Während Sie nicht möchten, demonitor/1 den gesamten Prozess, der den überwachten Port geschlossen, sollten Sie Referenzen verwenden.

1

Es ist in Ordnung, nur an die PID zu erinnern, wenn Sie nur ein kleines Projekt haben und nur einige Prozesse überwachen möchten. Ich würde jedoch empfehlen, die Referenz zu verwenden, da Projekte schnell wachsen und Sie möglicherweise nicht nur Prozesse überwachen möchten. Elixir verwendet unter der :erlang.monitor/2, die Sie auch ports und eine time_offset zwischen Erlang monotoner Zeit und Erlang Systemzeit überwachen können. Dies kann in der Docs here gefunden werden. Die Referenz ist allgemeiner und es ist eine bessere Praxis, die Referenz im Allgemeinen zu verwenden.

Hier ein kleines Beispiel, was ich sagen will:

iex(1)> :erlang.monitor(:time_offset, :clock_service) 
#Reference<0.0.3.100> 

iex(2)> :erlang.monitor(:process ,self()) 
#Reference<0.0.3.113> 
Verwandte Themen