How do I find the receiver of a send message?

I’m going through the codebase of an opensource project. It has some functions to send message to a process:

def cast_coordinator(msg) do
    case get_coordinator_pid() do
      nil -> nil
      pid -> send(pid, msg)
    end
  end
def get_coordinator_pid() do
    case Horde.Registry.lookup(Teiserver.ServerRegistry, "CoordinatorServer") do
      [{pid, _}] ->
        pid

      _ ->
        nil
    end
  end

I believe the process that handles it is defined here:

but I can’t see any receive function. Am I looking for the right function?

1 Like

OK after more reading seems like there is a handle_info function. What’s the difference between handle_info and receive ?

Check this: GenServer: Receiving “regular” messages.

But basically it’s for mostly handling messages sent via Process.send_after. But not only.

1 Like

TL;DR: receive is for any normal process, handle_info is your receive for GenServers.


receive is the low-level builtin for any process to read (while blocking) messages (sent by anyone) from its mailbox.

GenServer is an OTP abstraction built on top of processes and message passing. It uses receive under the hood to categorize incoming messages into one of three types:

  • “Calls” to your server

    These are messages sent via GenServer.call/3. They are received and forwarded to your implementation of handle_call/3. They represent messages from other processes that expect a reply from your server.

  • “Casts” to your server

    These are messages sent via GenServer.cast/2. They are received and forwarded to your implementation of handle_cast/2. They represent messages from other processes that don’t expect a reply from your server.

  • Everything else

    Of course, your GenServer is still just a process, anyone can send/2 it arbitrary normal messages.

    Since the GenServer framework uses receive to do message routing for you (and you should avoid doing so yourself inside a GenServer, outside of exceptional circumstances), it forwards all normally sent, non-cast-or-call messages to the handle_info/2 callback for you to handle as you see fit.

    This essentially is a way for your server process to handle messages from other processes that do not know or care that it is a GenServer.

    As @dimitarvp points out, it is often used internally in a server to send messages to itself—like little "to-do"s for work it needs to do later without blocking handling of casts/calls.

    But more generally, GenServers are just processes that abstract message handling + state management, and handle_info is the abstraction’s escape hatch for receive-ing arbitrary messages from other processes that do not know they are GenServers.

7 Likes

See also: GenServer n00b question - #6 by christhekeele

1 Like