\lstinline^any_tuple last_dequeued()^& Returns the last message that was dequeued from the actor's mailbox\newline\textbf{Note}: Only set during callback invocation \\
\lstinline^any_tuple last_dequeued()^& Returns the last message that was dequeued from the actor's mailbox\newline\textbf{Note}: Only set during callback invocation \\
\hline
\hline
\lstinline^actor_ptr last_sender()^& Returns the sender of the last dequeued message\newline\textbf{Note$_{1}$}: Only set during callback invocation\newline\textbf{Note$_{2}$}: Used by the function \lstinline^reply^ (see Section \ref{Sec::Send::Reply}) \\
\lstinline^actor_ptr last_sender()^& Returns the sender of the last dequeued message\newline\textbf{Note$_{1}$}: Only set during callback invocation\newline\textbf{Note$_{2}$}: Used implicitly to send response messages (see Section \ref{Sec::Send::Reply}) \\
\hline
\hline
\lstinline^vector<group_ptr> joined_groups()^& Returns all subscribed groups \\
\lstinline^vector<group_ptr> joined_groups()^& Returns all subscribed groups \\
@@ -25,13 +25,12 @@ Related functions, e.g., \lstinline^sync_send(...).then(...)^, behave the same,
...
@@ -25,13 +25,12 @@ Related functions, e.g., \lstinline^sync_send(...).then(...)^, behave the same,
\begin{itemize}
\begin{itemize}
\item
\item
\lstinline^send(self->last_sender(), ...)^ is \textbf{not} equal to \lstinline^reply(...)^.
\lstinline^send(self->last_sender(), ...)^ does \textbf{not} send a response message.
The two functions \lstinline^receive_response^ and \lstinline^handle_response^ will only recognize messages send via either \lstinline^reply^ or \lstinline^reply_tuple^.
\item
\item
A handle returned by \lstinline^sync_send^ represents \emph{exactly one} response message.
A handle returned by \lstinline^sync_send^ represents \emph{exactly one} response message.
Therefore, it is not possible to receive more than one response message.
Therefore, it is not possible to receive more than one response message.
Calling \lstinline^reply^ more than once will result in lost messages and calling \lstinline^handle_response^ or \lstinline^receive_response^ more than once on a future will throw an exception.
%Calling \lstinline^reply^ more than once will result in lost messages and calling \lstinline^handle_response^ or \lstinline^receive_response^ more than once on a future will throw an exception.
\item
\item
The future returned by \lstinline^sync_send^ is bound to the calling actor.
The future returned by \lstinline^sync_send^ is bound to the calling actor.
@@ -35,24 +35,18 @@ Choosing one or the other is merely a matter of personal preferences.
...
@@ -35,24 +35,18 @@ Choosing one or the other is merely a matter of personal preferences.
\subsection{Replying to Messages}
\subsection{Replying to Messages}
\label{Sec::Send::Reply}
\label{Sec::Send::Reply}
The return value of a message handler is used as response message.
During callback invokation, \lstinline^self->last_sender()^ is set.
During callback invokation, \lstinline^self->last_sender()^ is set.
This identifies the sender of the received message and is used implicitly by the functions \lstinline^reply^ and \lstinline^reply_tuple^.
This identifies the sender of the received message and is used implicitly to reply to the correct sender.
However, using \lstinline^send(self->last_sender(), ...)^ does \emph{not} reply to the message, i.e., synchronous messages will not recognize the message as response.
Using \lstinline^reply(...)^ is \textbf{not} equal to \lstinline^send(self->last_sender(), ...)^.
The function \lstinline^send^ always uses asynchronous message passing, whereas \lstinline^reply^ will send a synchronous response message if the received message was a synchronous request (see Section \ref{Sec::Sync}).
%Note that you cannot reply more than once.
To delay a response, i.e., reply to a message after receiving another message, actors can use \lstinline^self->make_response_handle()^.
The functions \lstinline^reply_to^ and \lstinline^reply_tuple_to^ then can be used to reply the the original request, as shown in the example below.
Strongly typed actors provide a convenient way of defining type-safe messaging interfaces.
Unlike ``dynamic actors'', typed actors are not allowed to change their behavior at runtime, neither are typed actors allowed to use guard expressions.
When calling \lstinline^become^ in a strongly typed actor, the actor will be killed with exit reason \lstinline^unallowed_function_call^.
Typed actors use \lstinline^typed_actor_ptr<...>^ instead of \lstinline^actor_ptr^, whereas the template parameters hold the messaging interface.
For example, an actor responding to two integers with a dobule would use the type \lstinline^typed_actor_ptr<replies_to<int, int>::with<double>>^.
\subsection{Spawning Typed Actors}
\label{sec:strong:spawn}
Actors are spawned using the function \lstinline^spawn_typed^.
The argument to this function call \emph{must} be a match expression as shown in the example below, because the runtime of libcppa needs to evaluate the signature of each message handler.
\begin{lstlisting}
auto p0 = spawn_typed(
on_arg_match >> [](int a, int b) {
return static_cast<double>(a) * b;
},
on_arg_match >> [](double a, double b) {
return make_cow_tuple(a * b, a / b);
}
);
// assign to identical type
using full_type = typed_actor_ptr<
replies_to<int, int>::with<double>,
replies_to<double, double>::with<double, double>
>;
full_type p1 = p0;
// assign to subtype
using subtype1 = typed_actor_ptr<
replies_to<int, int>::with<double>
>;
subtype1 p2 = p0;
// assign to another subtype
using subtype2 = typed_actor_ptr<
replies_to<double, double>::with<double, double>
>;
subtype1 p3 = p0;
\end{lstlisting}
All functions for message passing, linking and monitoring are overloaded to accept both types of actors.
As of version 0.8, strongly typed actors cannot be published (this is a planned feature for future releases).
\subsubsection{Continuations for Event-based Actors}
\subsubsection{Continuations for Event-based Actors}
\libcppa supports continuations to enable chaining of send/receive statements.
\libcppa supports continuations to enable chaining of send/receive statements.
The functions \lstinline^handle_response^ and \lstinline^message_future::then^ both return a helper object offering \lstinline^continue_with^, which takes a functor $f$ without arguments.
The functions \lstinline^handle_response^ and \lstinline^message_future::then^ both return a helper object offering the member function \lstinline^continue_with^, which takes a functor $f$ without arguments.
After receiving a message, $f$ is invoked if and only if the received messages was handled successfully, i.e., neither \lstinline^sync_failure^ nor \lstinline^sync_timeout^ occurred.
After receiving a message, $f$ is invoked if and only if the received messages was handled successfully, i.e., neither \lstinline^sync_failure^ nor \lstinline^sync_timeout^ occurred.