dsnipe
How to get keys of registered children (via Register)
Hello.
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!
Marked As Solved
dsnipe
Thank for the answer @arkgil!
In the end I figured out how Registry works. It links a key/value to a process which used to register it. So in my case each id is linked to a process (on starting procedure using :via) and when this process dies, the key automatically deletes from Registry (because linked to it).
Answer is – it’s impossible to iterate through these ids in Registry, but it’s possible to use Supervisor.which_children and get all children pids instead ![]()
I also use Registry to store an additional data for processes (using processes itself to register data), and it automatically cleans when a process killed.
Also Liked
darraghenright
I have to say, I was initially a bit perplexed by Registry.keys/2. I think I misunderstood its functionality based on some incorrect, preconceived notions.
I discovered this thread when trying to figure out my use case, so I figured I’d add a post in case it’s useful to someone in future.
I just wanted to get a list of all registered keys in a registry and assumed (without reading the docs to be fair) that Registry.keys/2 would do that, in much the same way that Registry.count/1 returns a count of all items in a registry.
I read through the docs a bit and realised that Registry.select/2 does this; i.e:
# get a list of keys
Registry.select(MyRegistry, [{{:"$1", :_, :_}, [], [:"$1"]}])
# get a list of two-element key/pid tuples
Registry.select(MyRegistry, [{{:"$1", :"$2", :_}, [], [{{:"$1", :"$2"}}]}])
adammokan
Looks like you have it figured out, but I have a sample project here - GitHub - amokan/registry_sample: Example application using the new Registry module in Elixir 1.4.0 · GitHub
In particular, you can look at how I used the Supervisor.which_children to get the registry keys here - registry_sample/lib/registry_sample/account_supervisor.ex at master · amokan/registry_sample · GitHub
arkgil
Second argument passed to Registry.keys/2 is a pid of a process which put an entry into registry (i.e. the one which called Registry.register/3 which is done behind the scenes when using :via option). I think that in your case it is a pid of MySupervisor because this is the process which called start_link/1 of your workers.
Try it with supervisor’s pid and let us know if that worked! ![]()
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









