8.10 Receive

  1. receive
  2. Pattern1 [when GuardSeq1] ->
  3. Body1;
  4. ...;
  5. PatternN [when GuardSeqN] ->
  6. BodyN
  7. end

Receives messages sent to the process using the send operator (!). The patterns Pattern are sequentially matched against the first message in time order in the mailbox, then the second, and so on. If a match succeeds and the optional guard sequence GuardSeq is true, the corresponding Body is evaluated. The matching message is consumed, that is, removed from the mailbox, while any other messages in the mailbox remain unchanged.

The return value of Body is the return value of the receive expression.

receive never fails. The execution is suspended, possibly indefinitely, until a message arrives that matches one of the patterns and with a true guard sequence.

Example:

  1. wait_for_onhook() ->
  2. receive
  3. onhook ->
  4. disconnect(),
  5. idle();
  6. {connect, B} ->
  7. B ! {busy, self()},
  8. wait_for_onhook()
  9. end.

The receive expression can be augmented with a timeout:

  1. receive
  2. Pattern1 [when GuardSeq1] ->
  3. Body1;
  4. ...;
  5. PatternN [when GuardSeqN] ->
  6. BodyN
  7. after
  8. ExprT ->
  9. BodyT
  10. end

ExprT is to evaluate to an integer. The highest allowed value is 16#FFFFFFFF, that is, the value must fit in 32 bits. receive..after works exactly as receive, except that if no matching message has arrived within ExprT milliseconds, then BodyT is evaluated instead. The return value of BodyT then becomes the return value of the receive..after expression.

Example:

  1. wait_for_onhook() ->
  2. receive
  3. onhook ->
  4. disconnect(),
  5. idle();
  6. {connect, B} ->
  7. B ! {busy, self()},
  8. wait_for_onhook()
  9. after
  10. 60000 ->
  11. disconnect(),
  12. error()
  13. end.

It is legal to use a receive..after expression with no branches:

  1. receive
  2. after
  3. ExprT ->
  4. BodyT
  5. end

This construction does not consume any messages, only suspends execution in the process for ExprT milliseconds. This can be used to implement simple timers.

Example:

  1. timer() ->
  2. spawn(m, timer, [self()]).
  3.  
  4. timer(Pid) ->
  5. receive
  6. after
  7. 5000 ->
  8. Pid ! timeout
  9. end.

There are two special cases for the timeout value ExprT:

  • infinity
  • The process is to wait indefinitely for a matching message; this is the same as not using a timeout. This can be useful for timeout values that are calculated at runtime.
  • 0
  • If there is no matching message in the mailbox, the timeout occurs immediately.