You already know the answer - you just aren’t creating the right conditions to see the effects.
defmodule Demo do
defp do_it(state) do
{_, num} = Process.info(self(), :message_queue_len)
IO.puts "queue length: #{inspect num}"
reply = {:reply, :hello, state}
cond do
num > 0 ->
reply
true ->
send(self(), :done)
reply
end
end
def init(_args) do
send(self(), :block) # get the first message in the mailbox
{:ok, []}
end
def handle_call(:hi, _from, state),
do: do_it(state)
def handle_info(:block, state) do
Process.sleep(1000) # block for one second
{:noreply, state}
end
def handle_info(:done, state) do
{:stop, :normal, state}
end
def terminate(reason, state) do
IO.puts "terminate: #{inspect reason} #{inspect state}"
end
end
{:ok, pid} = GenServer.start_link(Demo,[])
f = fn ->
GenServer.call(pid, :hi)
:ok
end
(for _ <- 1..4, do: Task.async(f))
|> Enum.map(&Task.await(&1))
$ elixir demo.exs
queue length: 3
queue length: 2
queue length: 1
queue length: 0
terminate: :normal []
$