I want to use Registry
module to register dynamically created children processes.
So I added registry into my supervisor tree:
def init([]) do
children = [
supervisor(Registry, [:unique, :my_registry]),
supervisor(MyManager, []),
# ...
]
opts = [strategy: :one_for_one, name: MySupervisor]
supervise(children, opts)
end
Registration of children happens like this:
def start_link(%{id: id}) do
GenServer.start_link(__MODULE__, [], name: {:via, Registry, {:my_registry, id}})
end
So, my questions is – how to get all keys (children pids) in my Registry.
I tried to use Registry.keys\2
, but without success.
def get_registry_pid do
Supervisor.which_children(MySupervisor)
|> Enum.filter(fn {id, _, _, _} -> id == Registry end)
|> List.first
|> elem(1) # get a Regisry pid from a tuple {id, pid, type, modules}
end
Registry.keys(:my_registry, get_registry_pid()) # returns []
# but
Registry.lookup(:my_registry, id) # returns PID as expected
Thanks in advance for any help!
This is a little late but I just came across this issue myself. There seems to be no official way to do this but digging through the Registry
source and reading something about :erts
I came up with the following solution:
defmodule MyApp.Sensor.Registry do
@doc """
Lists all the registered sensors from the registry.
"""
@spec list_sensors!(module) :: [{String.t(), pid, any}]
def list_sensors!(registry \\ __MODULE__) do
try do
# The args for `lookup_element` are taken from the private function
# `info/1` from the `Registry` module.
{_kind, _partitions, table, _pid_ets, _} =
:ets.lookup_element(registry, -1, 2)
# select_all is the result of `:ets.fun2ms(&(&1))` which works from iex
# but not when compiled for reasons beyond my comprehension
select_all = [{:"$1", [], [:"$1"]}]
:ets.select(table, select_all)
catch
:error, :badarg ->
raise ArgumentError, "#{inspect(registry)} is not running"
end
end
end
If I understand correctly, you need to extract all registered keys from a given Registry
.
Since Elixir 1.9.0 this can be achieved via Registry.select/2
as follows:
Registry.select(your_registry, [{{:"$1", :_, :_}, [], [:"$1"]}])
This will return the list of all known keys.
For more information on this function, here are the specs of Registry.select/2 on Hexdocs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With