Elixir's Mix and OTP Guide Chapter GenServer explains how to implement a registry server holding agents, using GenServer
.
Each agent's PID is kept in a map, where the keys are the agent's names given by the clients and the values are the agent's PIDs.
In order to avoid keeping references to dead agents, the guide proposes monitoring newly created agents using Process.monitor/1
and slightly modifying the state by adding a new map, called refs
, containing References (values returned by Process.monitor/1
) as keys and agents' names as values. It also shows how to handle monitoring messages using handle_info/2
to update refs
.
Process.monitor/1
receives a PID (e.g. #PID<0.66.0>
) as a parameter and returns a Reference (e.g. #Reference<0.0.0.551>
). The :DOWN
message caught by handle_info/2
provides both the PID and the Reference.
Since we know all the time both values: What are the benefits of using References as keys over using PIDs in refs
, if any?
This is a matter of consistency. While you have only processes monitored, there is no difference. But underlying :erlang.monitor/2
can monitor not only processes: there are ports etc, that basically have no PID
.
From the doc:
•
Object
The monitored entity, which triggered the event. When monitoring a local process or port,
Object
will be equal to thepid()
orport()
that was being monitored. When monitoring process or port by name,Object
will have format{RegisteredName, Node}
whereRegisteredName
is the name which has been used withmonitor/2
call andNode
is local or remote node name (for ports monitored by name,Node
is always local node name).
The summing up: Reference
is an entity, being monitored. It might be a process, a port, whatever. While you do not want to demonitor/1
the whole process that closed the port monitored, you should use references.