When a Genserver is dynamically started there are different options to specify its name:
{:global, term}
{:via, Registry, term} using a Registry module
The main difference seems that :global uses the Erlang module that supports multinode scenario, while the std Registry module is local only.
Is this the only difference? When should I use :global vs :via? And why other distributed registry exists (like Horde for example)?
Each of these mechanisms provides a different level of control over how your named process can be found.
Three ways to register a process:
My.Process - an atom, this name is visible in the current node.
{:global, My.Process} - using :global, this name is visible to all clustered nodes
{:via, some_registry, My.Process} - uses some_registry, which could be a Registry or another registry-like thing (like Horde.Registry)
Given the above, the answer to this question is pretty firmly “it depends on your use-case”. Each of these mechanisms provides different guarantees and trade-offs. Exactly what those guarantees and trade-offs are is too big a topic for a forum post, but I’d say that all of this falls into the category of “don’t worry about it until you have to.” If you’re curious, go read some docs on :global, Horde.Registry etc. to see how they differ.
To add to what was already said, {:global, name} makes this name (and hence the process) unique across nodes. For instance, Mox.Server starts named globally to avoid several instances running on connected nodes.
:via is typically used with dynamic supervision trees.
module() is unique within this particular node only.
Thank you, what is not clear to me is why/when, in a distributed scenario, I should choose (for example) Horde Registry (based on ets) over :global module.
I read the docs and search the web, but I can’t find a deep explanation.
The use-cases differ. Horde provides somewhat similar to DynamicSupervisor, but distributed. Basically, if you have a DynamicSupervisor and want to drop-in painlessly [to some extent] the cluster support, Horder might help.
:global is different, it makes sense in distributed clusters only and it means a singleton across the cluster.
Generally speaking, until you are certain you need Horde/:global/whatever, you should not bother. DynamicSupervisor/PartitionSupervisor would serve you best for non-distrubuted app (let alone simple module(), or even unnamed processes.)