Hey! This was pretty useful, I’ve just started playing around with the Registry and this confirmed…

Good questions. I’ll do my best to answer them.

What’s the benefit of starting the Registry process as a supervisor vs a worker ?

To be honest, I just followed the documentation for Registry and have stuck with this supervisor syntax they show (see this section).

What benefits do we get from the via tuple? I saw the pattern in a blog entry that talked about gproc but I couldn’t find a reason / source for it.

To me, the benefit is that GenServer handles this approach out of the box for naming and I do not have to worry about a whole lot in regards to custom logic.

The via tuple not only provides a name to the GenServer but it also specifies the mechanism to create or lookup the identifier, in our case we are specifying Registry. At the end of the day, it is a contract or interface with any registration mechanism that implements handlers for four specific functions mentioned on the GenServer naming conventions page.

Because the via depends on a module that implements these handlers, it makes it trivial to swap out Registry with something else like gproc:global, or your own registration module. For example, maybe you want to make a custom in-memory registry using a simple Agent or something like that. As long as it provides the handlers mentioned in the docs, it will just work out of the box for anything setup using the via.

So {:via, Registry, {:account_process_registry, account_id}} could easily become {:via, MyCoolRegistry, {:account_process_registry, account_id}} assuming I had a module called MyCoolRegistry that implemented the functions register_name/2, unregister_name/1, whereis_name/1, and send/2.

Why do we give the via tuple as the name? This might be something you answer as part of 2, but just in case you don’t…

Again, this comes down to the GenServer name registration options mentioned above and specified in the documentation.

Just naming the GenServer inside start_link isn’t really where the magic is with this. The gain is when you go to interact with that GenServer you created later on. You’ll notice the via_tuple function I created is in every call/castGenServer.call(via_tuple(id), :foo). If I were not using this approach, I’d have to keep track of the PID internally for each GenServer and be sure to pass it along correctly on those same calls. Obviously if you just spawn a GenServer and never need to call a function on it after that, you do not need this at all. So if you have a short-lived worker scenario, with no exposed API, I’d not even worry about this.

Also note that the via_tuple function itself could be named anything and still behave the same way. As long as it returns a tuple containing{:via, module, term} it will work.

I hope that explains things a little bit. Having said that, I know I pulled out the “it says so in the docs” argument a lot. If anyone else has more to add to this, feel free!

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.