I am making basic Elixir server/client module that can send/receive asynchronous messages. The module looks like following.
defmodule Bitcoin.WorkerOne do
use GenServer
def start_link(opts) do
IO.puts " - Worker 1 started - "
GenServer.start_link(__MODULE__,:ok, opts)
end
def set_message(server, name, mid) do
GenServer.cast(server, {:set_message, name})
end
#callbacks
def init(:ok) do
names = []
{:ok, names}
end
def handle_cast({:set_message, name},names) do
IO.puts "- new state is - "
names = names ++name
IO.inspect names
{:noreply,names}
end
end
I am initiating the processes through iex console using.
{:ok, pid1} = Bitcoin.WorkerOne.start_link([])
Bitcoin.WorkerOne.get_message(pid1, ["one"])
After the above , the state gets change to ['one'] (initially empty list). I want to send a notification back to the server that the state has been updated. Can I call 'Genserver.cast'
inside the handle_cast
, in order to send a message back?
You should include the sender's pid in the message to the server when using casts where you want to send a notification, but it's better to use calls combined with
GenServer.reply/2
, returning{:noreply, state}
in thehandle_call
callback for that use case, to get the guarantee that the server received the request. Manually reimplementing replies is a lot of work depending on what guarantees you need, so you should avoid it.