Discard late replies with process aliases

almirsarajcic

almirsarajcic

46 minutes ago

0 comments

Send hand-rolled request replies to a process alias, then deactivate the alias when the caller stops waiting.

defmodule ReplyClient do
  def request(server, message, timeout) do
    reply_to = Process.alias()
    send(server, {:request, reply_to, message})

    receive do
      {^reply_to, value} ->
        Process.unalias(reply_to)
        {:ok, value}
    after
      timeout ->
        Process.unalias(reply_to)
        {:error, :timeout}
    end
  end
end

An alias is a reference that can receive messages on behalf of the process that created it. The server replies with send(reply_to, {reply_to, result}), not by sending to the caller PID.

Once Process.unalias/1 deactivates that alias, later sends to it are dropped. A slow reply therefore cannot arrive in the caller’s mailbox after the timeout and get mistaken for a future message.

Deactivating an alias does not cancel the server’s work. If the operation itself must stop, add an explicit cancellation protocol or run it in a process you can terminate safely.

Current GenServer.call/3 already uses aliases internally. Reach for Process.alias/0 when implementing your own request/reply protocol around plain processes, ports, or custom messaging.

Process.alias/0 docs

Comments (0)

Sign in with GitHub to join the discussion