There is this code in programming elixir 1.3
Seems like the use of a global registry is a side effect. Is there any better way to do this or is this the “recommended” way?
defmodule Ticker do
@interval 2000 # 2 seconds
@name :ticker
def start do
pid = spawn(__MODULE__, :generator, [[]])
:global.register_name(@name, pid)
end
def register(client_pid) do
send :global.whereis_name(@name), { :register, client_pid }
end
def generator(clients) do
receive do
{ :register, pid } ->
IO.puts "registering #{inspect pid}"
generator([pid|clients])
after
@interval ->
IO.puts "tick"
Enum.each clients, fn client ->
send client, { :tick }
end
generator(clients)
end
end
end
defmodule Client do
def start do
pid = spawn(__MODULE__, :receiver, [])
Ticker.register(pid)
end
def receiver do
receive do
{ :tick } ->
IO.puts "tock in client"
receiver
end
end
end
Well, the code in the book is written a particular way in order to teach you particular things. In production code you basically never use spawn directly, nor do you manage your own receive loop.
Seems like the use of a global registry is a side effect.
Yes, it is.
Is there any better way to do this or is this the “recommended” way?
It depends on what “this” is. If “this” were to just be "print tick
every N seconds` then there’s definitely more “proper” ways to do it. But in the context of the book, “this” is “learn these things”.
1 Like
“this” meaning passing message to another node and have that node respond back without using the global registry / side effects
It’s a concession to practicality:
- If you have a PID you can simply use that - the issue is how do you get that PID in the first place? At the very minimum the registered
name
gives you a first point of contact; that first point of contact could give you a PID to use for the rest of the conversation - and that PID could be different from the one returned by Process.whereis(name)
.
- However there is also the issue of fault tolerance. Once a process terminates the PID is useless as the process that may replace it will have a different PID - a registered
name
gets around that problem as the replacement process can be registered under the name
.