Agent identity - pid or name

Excuse noob questions.

Using agent. I see examples in the doc that do

{:ok, pid} = Agent.start_link(fn -> 42 end)
Agent.cast(pid, fn state -> state + 1 end)

but also

 def start_link(initial_value) do
    Agent.start_link(fn -> initial_value end, name: __MODULE__)
  end

  def value do
    Agent.get(__MODULE__, & &1)
  end

The doc doesnt say that I can use a name instead of a pid. Is this a universal thing, that anywhere a pid is required a name can be used (if a name was supplied for the process), or is it just for the Agent functions.

Is it more expensive to use a name vs a pid? Seems like it should be.

I guess it’s more practical to use name instead of pid, but a good reason, when You work with gen_servers… and they restart, then the pid will change, but not the name

“An agent is bound to the same name registration rules as GenServers.” -

Under the name registration: Agent — Elixir v1.12.3

What it references: GenServer — Elixir v1.12.3

2 Likes

aha, OK, I assumed that was going to talk about what names are valid, what happens with dup names… But I see it also says that a name can be used in place of pid

1 Like

Every process has a pid. You can also choose to register a process with a well known name, with the following benefit:

  • Since the name is well known (often just the module name), you do not need to store the pid to be able to refer to the process later
  • If your process crashed ans restarted by the supervisor, the pid will be different but the name will be the same, so in many cases, your application keep running despite the crash of a process

The second point is one of the source of OTP’s robustness.

1 Like

There’s also many registries. The :name option uses a built in registry, OTP ships with :global, elixir ships Registry and there are many third party registries. They all do process registration, but all of them use different mechanisms to do so and therefore fit for well for different types of problems / usecases.

2 Likes

The docs for Process.register/2 are what you’re looking for. You can register any atom (remember module names are atoms) with a few exceptions like nil (see the list in the docs). The registration is synchronous on the node and you cannot register duplicate names on one node.

It is very easy to build your own process registry in Elixir/Erlang (a GenServer with a map of %{name => pid} is all you need), but without the built-in registry there would of course be no way to look up the pid of your registry! :slight_smile:

1 Like