View Source ProcessRegistry
The ProcessRegistry
is a global registry that keeps track of all the processes in the system.
It is used to look up a process by its name, and to register a process with a name.
It's recommended to interact with ProcessRegistry
through the main ProcessHub
API module.
By default ProcessRegistry
is using pubs/subs mechanism to notify subscribers about changes in the registry. This implementation can be replaced with ProcessHub.Strategy.Synchronization.Gossip
or
custom implementation.
We will skip the boiler plate code for starting the child processes and focus on the registry itself.
Querying the whole registry
We will start of by querying the whole registry with ProcessHub.process_list/2
function.
This function allows us to query the whole registry or a specific hub and specify if we want to include remote processes or not.
If we choose to exclude remote processes, the node names wont be included in the returned list.
We can switch between :global
and :local
mode by passing the second argument to the function.
The ProcessHub.process_list/2
function is the most efficient way to query the whole registry because
the data is coming from the local registry and no network calls are made.
iex> ProcessHub.process_list(:my_hub, :global)
[
my_process_1: [two@anuar: #PID<23772.233.0>],
my_process_2: [one@anuar: #PID<0.250.0>],
my_process_3: [one@anuar: #PID<0.253.0>],
my_process_4: [one@anuar: #PID<0.256.0>],
my_process_5: [one@anuar: #PID<0.259.0>],
my_process_6: [one@anuar: #PID<0.262.0>],
my_process_7: [one@anuar: #PID<0.265.0>],
my_process_8: [two@anuar: #PID<23772.254.0>],
my_process_9: [one@anuar: #PID<0.271.0>],
my_process_10: [one@anuar: #PID<0.274.0>]
]
iex> ProcessHub.process_list(:my_hub, :local)
[
my_process_2: #PID<0.250.0>,
my_process_3: #PID<0.253.0>,
my_process_4: #PID<0.256.0>,
my_process_5: #PID<0.259.0>,
my_process_6: #PID<0.262.0>,
my_process_7: #PID<0.265.0>,
my_process_9: #PID<0.271.0>,
my_process_10: #PID<0.274.0>
]
Another similar option is ProcessHub.process_registry/1
which dumps the whole registry into a map
including other metadata stored in the registry.
iex> ProcessHub.process_registry(:my_hub)
%{
my_process_1: {%{id: :my_process_1, start: {MyProcess, :start_link, []}},
[two@anuar: #PID<23772.233.0>]},
my_process_2: {%{id: :my_process_2, start: {MyProcess, :start_link, []}},
[one@anuar: #PID<0.250.0>]},
my_process_3: {%{id: :my_process_3, start: {MyProcess, :start_link, []}},
[one@anuar: #PID<0.253.0>]},
my_process_4: {%{id: :my_process_4, start: {MyProcess, :start_link, []}},
[one@anuar: #PID<0.256.0>]},
my_process_5: {%{id: :my_process_5, start: {MyProcess, :start_link, []}},
[one@anuar: #PID<0.259.0>]},
my_process_6: {%{id: :my_process_6, start: {MyProcess, :start_link, []}},
[one@anuar: #PID<0.262.0>]},
my_process_7: {%{id: :my_process_7, start: {MyProcess, :start_link, []}},
[one@anuar: #PID<0.265.0>]},
my_process_8: {%{id: :my_process_8, start: {MyProcess, :start_link, []}},
[two@anuar: #PID<23772.254.0>]},
my_process_9: {%{id: :my_process_9, start: {MyProcess, :start_link, []}},
[one@anuar: #PID<0.271.0>]},
my_process_10: {%{id: :my_process_10, start: {MyProcess, :start_link, []}},
[one@anuar: #PID<0.274.0>]}
}
There's also a third option ProcessHub.which_children/2
but is highly discouraged to use and may
be deprecated in the future.
This function does network calls to all nodes in the cluster to get the list of processes and also may lead to memory and performance issues when used with large nuber of processes.
It's using the Supervisor.which_children/1
function under the hood which has stated in the
documentation: Note that calling this function when supervising a large number of children
under low memory conditions can cause an out of memory exception.
Here is an example of how to use ProcessHub.which_children/2
function:
iex> ProcessHub.which_children(:my_hub, [:global])
[
one@anuar: [
{:my_process_10, #PID<0.274.0>, :worker, [MyProcess]},
{:my_process_9, #PID<0.271.0>, :worker, [MyProcess]},
{:my_process_7, #PID<0.265.0>, :worker, [MyProcess]},
{:my_process_6, #PID<0.262.0>, :worker, [MyProcess]},
{:my_process_5, #PID<0.259.0>, :worker, [MyProcess]},
{:my_process_4, #PID<0.256.0>, :worker, [MyProcess]},
{:my_process_3, #PID<0.253.0>, :worker, [MyProcess]},
{:my_process_2, #PID<0.250.0>, :worker, [MyProcess]}
],
two@anuar: [
{:my_process_8, #PID<23772.254.0>, :worker, [MyProcess]},
{:my_process_1, #PID<23772.233.0>, :worker, [MyProcess]}
]
]
iex> ProcessHub.which_children(:my_hub, [:local])
{:one@anuar,
[
{:my_process_10, #PID<0.274.0>, :worker, [MyProcess]},
{:my_process_9, #PID<0.271.0>, :worker, [MyProcess]},
{:my_process_7, #PID<0.265.0>, :worker, [MyProcess]},
{:my_process_6, #PID<0.262.0>, :worker, [MyProcess]},
{:my_process_5, #PID<0.259.0>, :worker, [MyProcess]},
{:my_process_4, #PID<0.256.0>, :worker, [MyProcess]},
{:my_process_3, #PID<0.253.0>, :worker, [MyProcess]},
{:my_process_2, #PID<0.250.0>, :worker, [MyProcess]}
]}
Querying a specific child
To quickly get the PID of the running process by it's child_id
we can use the
ProcessHub.get_pid/2
function which returns the process identifier.
iex> ProcessHub.get_pid(:my_hub, :my_process_10)
#PID<0.228.0>
Now when utilizing replication strategies we should default to another function ProcessHub.get_pids/2
which returns a list of PIDs for the given child_id
.
iex> ProcessHub.get_pids(:my_hub, :my_process_10)
[#PID<0.228.0>]
We may also query the whole child info by using the ProcessHub.which_children/2
function.
This function also gives us the child_spec
.
iex> ProcessHub.child_lookup(:my_hub, :my_process_10)
{
%{id: :my_process_10, start: {MyProcess, :start_link, []}},
[one@anuar: #PID<0.228.0>]
}