\section{Blocking API}
\label{Sec::BlockingAPI}

Besides event-based actors (the default implementation), \lib also provides context-switching and thread-mapped actors that can make use of the blocking API.
Those actor implementations are intended to ease migration of existing applications or to implement actors that need to have access to blocking receive primitives for other reasons.

Event-based actors differ in receiving messages from context-switching and thread-mapped actors: the former define their behavior as a message handler that is invoked whenever a new messages arrives in the actor's mailbox (by using \lstinline^become^), whereas the latter use an explicit, blocking receive function.

\subsection{Receiving Messages}

The function \lstinline^receive^ sequentially iterates over all elements in the mailbox beginning with the first.
It takes a message handler that is applied to the elements in the mailbox until an element was matched by the handler.
An actor calling \lstinline^receive^ is blocked until it successfully dequeued a message from its mailbox or an optional timeout occurs.

\begin{lstlisting}
self->receive (
  on<int>() >> // ...
);
\end{lstlisting}

The code snippet above illustrates the use of \lstinline^receive^.
Note that the message handler passed to \lstinline^receive^ is a temporary object at runtime.
Hence, using receive inside a loop would cause creation of a new handler on each iteration.
\lib provides three predefined receive loops to provide a more efficient but yet convenient way of defining receive loops.

\begin{tabular*}{\textwidth}{p{0.47\textwidth}|p{0.47\textwidth}}
\lstinline^// DON'T^ & \lstinline^// DO^ \\
\begin{lstlisting}
for (;;) {
  receive (
    // ...
  );
}
\end{lstlisting} & %
\begin{lstlisting}
receive_loop (
  // ...
);
\end{lstlisting} \\
\begin{lstlisting}
std::vector<int> results;
for (size_t i = 0; i < 10; ++i) {
  receive (
    on<int>() >> [&](int value) {
      results.push_back(value);
    }
  );
}
\end{lstlisting} & %
\begin{lstlisting}
std::vector<int> results;
size_t i = 0;
receive_for(i, 10) (
  on<int>() >> [&](int value) {
    results.push_back(value);
  }
);
\end{lstlisting} \\
\begin{lstlisting}
size_t received = 0;
do {
  receive (
    others >> [&]() {
      ++received;
    }
  );
} while (received < 10);
\end{lstlisting} & %
\begin{lstlisting}
size_t received = 0;
do_receive (
  others >> [&]() {
    ++received;
  }
).until([&] { return received >= 10; });
\end{lstlisting} \\
\end{tabular*}

The examples above illustrate the correct usage of the three loops \lstinline^receive_loop^, \lstinline^receive_for^ and \lstinline^do_receive(...).until^.
It is possible to nest receives and receive loops.

\begin{lstlisting}
self->receive_loop (
  on<int>() >> [&](int value1) {
    self->receive (
      on<float>() >> [&](float value2) {
        cout << value1 << " => " << value2 << endl;
      }
    );
  }
);
\end{lstlisting}

\clearpage
\subsection{Receiving Synchronous Responses}

Analogous to \lstinline^sync_send(...).then(...)^ for event-based actors, blocking actors can use \lstinline^sync_send(...).await(...)^.

\begin{lstlisting}
void foo(blocking_actor* self, actor testee) {
  // testee replies with a string to 'get'
  self->sync_send(testee, get_atom::value).await(
    [&](const std::string& str) {
      // handle str
    },
    after(std::chrono::seconds(30)) >> [&]() {
      // handle error
    }
  );
}
\end{lstlisting}

\subsection{Mixing Actors and Threads with Scoped Actors}

The class \lstinline^scoped_actor^ offers a simple way of communicating with CAF actors from non-actor contexts.
It overloads \lstinline^operator->^ to return a \lstinline^blocking_actor*^.
Hence, it behaves like the implicit \lstinline^self^ pointer in functor-based actors, only that it ceases to exist at scope end.

\begin{lstlisting}
void test() {
  scoped_actor self;
  // spawn some monitored actor
  auto aut = self->spawn<monitored>(my_actor_impl);
  self->sync_send(aut, "hi there").await(
    ... // handle response
  );
  // self will be destroyed automatically here; any
  // actor monitoring it will receive down messages etc.
}
\end{lstlisting}

Note that \lstinline^scoped_actor^ throws an \lstinline^actor_exited^ exception when forced to quit for some reason, e.g., via an \lstinline^exit_msg^.
Whenever a \lstinline^scoped_actor^ might end up receiving an \lstinline^exit_msg^ (because it links itself to another actor for example), the caller either needs to handle the exception or the actor needs to process \lstinline^exit_msg^ manually via \lstinline^self->trap_exit(true)^.
