Say I have a message queue implemented as a GenServer, something like this
#... def start_link ...
def init(state) do
{:ok, schedule(state)}
end
# schedule processing every 500 ms
defp schedule(state) do
Process.send_after(self(), :process, 500)
state
end
def handle_info(:process, state) do
{:noreply, process_queue(state)}
end
# catch all handle_info
def process_queue(state) do
# concurrently processes each entry and deletes it from the state
# schedule(state)
end
def put(data) do
GenServer.call(__MODULE__, {:put, entry})
end
def handle_call({:put, entry}, _from, state) do
{:reply, :ok, [entry | state]}
end
The question is about the relationship between handle_call and handle_info that both use the same state. From what I understand there is no way the state breaks, meaning while process_queue does its job (which may take a while) any put calling handle_call will have to wait, is that right?
If I want put to return immediately and add entries to queue after handle_info is done, I’d have to switch from call to cast, and I’m good?
Is there a nicer / simpler approach to achieve that or is this one good? Shouldn’t I handle such state using ETS (that’s what I’m switching from at the moment)?






















