Message queue length of a GenServer

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 []
$
3 Likes