GenServer name registration: :global vs :via tuple

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)?

Thank you
ema

4 Likes

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.

9 Likes

:via is generic. You can write your own module that will handle via tuples. If I’m not mistaken, {:via, :global, global_name} Also works

2 Likes

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.

4 Likes

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.

thx

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.)

2 Likes