Can we access a GenServer by name?

defmodule Downloader do
  use GenServer
   
 ## Client
      def start(s), do: GenServer.start(__MODULE__, s, name: s.name)
      def stop, do: GenServer.call(__NAME__, :stop)
      def info, do: GenServer.call(__NAME__, :info)

Can we access the __NAME__ of the GenServer which we used in GenServer.start ?

In this case I would like to have Downloader1, Downloader2, Downloader3 which are fixed names in the system

1 Like

Hi,

The short answer to this is that yes, you can access the genserver by name, but there is no __NAME__.

The nuanced answer is that you can pass the :name option to the GenServer.start/3 or GenServer.start_link/3 function. What you provide as the value of the :name option will become the server’s alias, and you can now “access” the server via the alias wherever you would normally use a pid. You can find more information in the GenServer docs - specifically, search for the phrase “name registration”. (Please note that there are restrictions on what the value of :name can be.

Since there is no __NAME__, what you can do is create a function that takes one parameter (the name of the server), and then delegates to GenServer.stop, which uses the argument to stop the correct server. For example:

def stop(server) do would delegate to GenServer.stop(server, :stop).

I hope this helpful.

3 Likes

You may want to have a look at gproc. It would let you use names like {:downloader, 1} with via tuples. This article explains how.

4 Likes

Thanks, your suggestion was perfect.

  defp download(1, id, file_name, size), do: Downloader.download(Downloader1, id, file_name, size)
  defp download(2, id, file_name, size), do: Downloader.download(Downloader2, id, file_name, size)
  defp download(3, id, file_name, size), do: Downloader.download(Downloader3, id, file_name, size)
  defp download(4, id, file_name, size), do: Downloader.download(Downloader4, id, file_name, size)
  defp download(5, id, file_name, size), do: Downloader.download(Downloader5, id, file_name, size)
2 Likes

I would highly recommend this video : https://www.youtube.com/watch?v=y_b6RTes83c

It is Saša Jurić and covers a number of techniques for registering and subsequently discovering running processes. It covers a lot of the techniques mentioned here and more.

7 Likes

@CharlesO - I’m glad that this worked, but it does not look like idiomatic Elixir (though I don’t have the context of the rest of the code). Process discovery is a topic that is treated very crisply and clearly by @sasajuric in his book Elixir in Action. If you have the time, his talk (already linked to in this post) is fantastic, but I got more from the book. I’m also writing a post on this topic, but I don’t plan to have that ready until this Saturday.

1 Like

There is also a tiny library in Erlang, called Syn, where you can easily register process with any name/meta, and also join them into groups.
More about Syn in this post

2 Likes