A GenServer handle_call/3 implementation can return :continue to invoke an additional function. Are there any guarantees as to when this function will run relative to other messages?
For example, consider this module that just keeps a running counter:
defmodule Tmp do
use GenServer
def start_link(opts), do: GenServer.start_link(__MODULE__, 0, opts)
def incr(tmp), do: GenServer.call(tmp, :incr)
@impl true
def init(state), do: {:ok, state}
@impl true
def handle_call(:incr, _from, n) do
{:reply, n, n, {:continue, :incr}}
end
@impl true
def handle_continue(:incr, n) do
{:noreply, n+1}
end
end
When you call Tmp.incr/1, the handle_call/3 method returns the current value of the counter, but then also returns :continue. This causes the GenServer infrastructure to call handle_continue/2.
If I call Tmp.incr/1 twice in succession, am I guaranteed to get incrementing values? Or is it possible that handle_call/3 will be called twice before handle_continue/2 is called at all?
iex> {:ok, tmp} = Tmp.start_link([])
iex> Tmp.incr(tmp)
0
iex> Tmp.incr(tmp)
1
# If I type fast enough, will this ever return 0?