jonnifyelixir
F3 / F3.07 / messages

F3.07 · part 2 of 3

Sending & receiving messages

Processes share no memory, so they coordinate by messages. send(pid, term) drops any term into the target's mailbox and returns at once; receive pattern-matches messages out of the mailbox, one at a time. A message can carry a PID, which is how the receiver knows where to reply. That is the entire actor protocol.

The portal runs a small summary server: send it a request with your own PID, and it sends a result back. Choose a message and watch which receive clause matches — and what happens to a message that matches none.

The mailbox and receive

The server loops on a receive with two clauses. A matching message is pulled from the mailbox and handled; a message that matches no clause is not discarded — it stays queued for a later receive. Choose a message and see the match.

The incoming message · select one

INCOMING MESSAGE · FRONT OF MAILBOX {:summarize, %User{email: "ada@portal.dev"}, from} receive do {:ping, from} -> send(from, :pong) matched {:summarize, e, from} -> send(from, Summary.summarize(e)) matched REPLY SENT TO CALLER "ada@portal.dev · student"

      

Selective receive is the quiet detail: a message that no clause matches waits in the mailbox rather than being dropped. A process reads exactly the messages it is ready for, in the order it chooses.

Replying with self()

Send is one-way, so a request that wants an answer includes the caller's PID, taken from self/0. The server sends its result there, and the caller runs its own receive to collect it. Two one-way sends make a round trip.

# caller side
send(server, {:summarize, user, self()})
receive do
  summary -> summary        # => "ada@portal.dev · student"
end

# server side, inside its loop
receive do
  {:summarize, entity, from} ->
    send(from, Portal.Summary.summarize(entity))
end

The idea

Coordinate without shared memory, and reply by handing back a return address.

In Elixir

send appends to a PID's mailbox; receive matches it out; include self() so the server can answer.

Next: holding state in a loop — the recursive receive that lets a process remember between messages.

References

Primary sources for this lesson, and where it connects in the course.