fireproofsocks

fireproofsocks

The use for keys: :duplicate in Registries?

I find it surprising that :via is not supported for duplicate registries. If you can’t register a pool of processes under the same name what exactly is the use-case for having duplicate-key registries? The docs include an example of dispatching (Registry — Elixir v1.21.0-dev), but I’m not clear how you would even put a process into a custom Registry if :via is not allowed. What am I missing? How do you actually use a custom Registry with duplicate keys?

Most Liked

al2o3cr

al2o3cr

:via isn’t specifically related to Registry, it’s just a fancy way to tell :gen’s name handling to call register_name and whereis_name on a specified module:

https://github.com/erlang/otp/blob/9ff030be08a162c12a13d5dfdf24f90048a24233/lib/stdlib/src/gen.erl#L622-L640

(related: Elixir’s wrappers transform a bare atom name into {:local, name})

Conversely, Registry isn’t otherwise related to process naming - it’s just a key-value store that automatically cleans up keys when the registering process exits.

The simplest thing to build with a :duplicate registry is a local publish-subscribe bus:

  • processes that are interested in a topic {:foo, 123} use Registry.register to “subscribe” to that key
  • when a message needs to be delivered for topic {:foo, 123}, the sender uses Registry.dispatch to send it to each PID
  • when a process that’s subscribed to a topic stops, its registration is automatically cleaned up

You might even use both a :unique and a :duplicate registry with the same keys, for instance in the classic “multiplayer game” architecture:

  • the :unique registry tracks a GenServer per “game”. A :via tuple pointing to this registry is used when sending moves, joins, etc to the game
  • the :duplicate registry tracks the Liveview processes of players per “game”, and is used to distribute updates to all players
fireproofsocks

fireproofsocks

Thank you for the informative responses! This is stuff that I’m going to have to ponder about for a while, but I see the set/get is pretty straightforward using Registry.register/3 and Registry.lookup/2:

iex> {:ok, _} = Registry.start_link(keys: :duplicate, name: ClusterRegistry)
iex> Registry.register(ClusterRegistry, :group, "a")
iex> Registry.register(ClusterRegistry, :group, "b")
iex> Registry.register(ClusterRegistry, :group, "c")
iex> Registry.lookup(ClusterRegistry, :group)
[{#PID<0.148.0>, "a"}, {#PID<0.148.0>, "b"}, {#PID<0.148.0>, "c"}]

What is interesting to me is that Registry.register/3 really is all about storing the current process – the value seems almost secondary. The other thing that is interesting is that when a process terminates, anything that it registered gets removed (as. you pointed out Matt):

iex> Task.start(fn -> 
  Registry.register(ClusterRegistry, :group, "hello?") 
  Process.sleep(10_000)
end)
iex> Registry.lookup(ClusterRegistry, :group)
[{#PID<0.148.0>, "a"}, {#PID<0.148.0>, "b"}, {#PID<0.148.0>, "c"}, {#PID<0.148.0>, "hello?"}]

# Wait 10 seconds
iex> Registry.lookup(ClusterRegistry, :group)
[{#PID<0.148.0>, "a"}, {#PID<0.148.0>, "b"}, {#PID<0.148.0>, "c"}]

I feel like I’m only becoming dimly aware of the things that you can do with these tools…

Where Next?

Popular in Questions Top

Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
vac
Hi, I’m quite new in Elixir and I’m trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and I...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New

Other popular topics Top

sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 42920 311
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
Lily
In templates/appointment/index.html.eex: &lt;%= for appointment &lt;- @appointments do %&gt; &lt;tr&gt; &lt;td&gt;&lt;%= appoi...
New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a &gt; b) do {:ok, "a"} end if (a &lt; b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36128 110
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New

We're in Beta

About us Mission Statement