Elixir Code Not receiving messages

This is a piece of code for testing the receive block

defmodule ElixirBasics.Runner do
  def start do
    IO.puts("Started the process at #{inspect(self())}")
    receive_msg()
  end

  def receive_msg do
    receive do
      {:ok, msg} ->
        IO.puts("received this message #{msg}")

      _ ->
        IO.puts("received invalid msg type")
    end

    receive_msg()
  end
end

ElixirBasics.Runner.start()
Process.sleep(:infinity)

This is present inside a .ex file and running with the command mix run lib/runner.ex. Now I am trying to send messages to the spawned process using Process.send(pid of process, {:ok, “hello”}, [ ]). I got :ok when trying to run the send command but the messages weren’t handled by receive block. The IO statements weren’t getting logged into the console. Can anyone point out my mistake?

This works

iex(10)> pid = spawn(ElixirBasics.Runner, :start, [])
Started the process at #PID<0.118.0>
#PID<0.118.0>
iex(11)> Process.send(pid, {:ok, “hello”}, [])
received this message hello
:ok

or this if you want to run from same file -

defmodule ElixirBasics.Runner do
  def start do
    IO.puts("Started the process at #{inspect(self())}")
    receive_msg()
  end

  def receive_msg do
    receive do
      {:ok, msg} ->
        IO.puts("received this message #{msg}")

      _ ->
        IO.puts("received invalid msg type")
    end

    receive_msg()
  end
end

pid = spawn(ElixirBasics.Runner, :start, [])
Process.send(pid, {:ok, "hello"}, [])

4 Likes

FWIW, Process.send will not return an error if you try to send to a PID that doesn’t exist. There are only two not-:ok values it will return, and those only happen if you ask for them explicitly (:noconnect and :nosuspend)

2 Likes

Note however that send() will raise if the target is a registered name which is not found, which is one of the ugliest design mistakes in OTP (and there really aren’t many).

Strangely I just noticed that this is actually not documented for the Elixir Kernel.send/2. They do at least link to the Erlang docs, but I think it should be explicitly mentioned.

1 Like