Commit bb3d7991 authored by Dominik Charousset's avatar Dominik Charousset

manual update for upcoming version 0.8

parent 637d7d9a
......@@ -8,3 +8,6 @@ build-gcc/*
Makefile
bin/*
lib/*
manual/manual.pdf
manual/build-pdf/*
manual/build-html/*
No preview for this file type
......@@ -50,7 +50,7 @@ class local_actor;
\hline
\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
\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
\lstinline^vector<group_ptr> joined_groups()^ & Returns all subscribed groups \\
\hline
......
......@@ -25,13 +25,12 @@ Related functions, e.g., \lstinline^sync_send(...).then(...)^, behave the same,
\begin{itemize}
\item
\lstinline^send(self->last_sender(), ...)^ is \textbf{not} equal to \lstinline^reply(...)^.
The two functions \lstinline^receive_response^ and \lstinline^handle_response^ will only recognize messages send via either \lstinline^reply^ or \lstinline^reply_tuple^.
\lstinline^send(self->last_sender(), ...)^ does \textbf{not} send a response message.
\item
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.
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
The future returned by \lstinline^sync_send^ is bound to the calling actor.
......
......@@ -66,13 +66,14 @@ void mirror() {
// wait for messages
become (
// invoke this lambda expression if we receive a string
on_arg_match >> [](const string& what) {
on_arg_match >> [](const string& what) -> string {
// prints "Hello World!" via aout (thread-safe cout wrapper)
aout << what << endl;
// replies "!dlroW olleH"
reply(string(what.rbegin(), what.rend()));
// terminates this actor ('become' otherwise loops forever)
// terminates this actor afterwards;
// 'become' otherwise loops forever
self->quit();
// replies "!dlroW olleH"
return string(what.rbegin(), what.rend());
}
);
}
......
......@@ -18,7 +18,7 @@ Otherwise, the actor accepts all incoming connections (\lstinline^INADDR_ANY^).
publish(self, 4242);
become (
on(atom("ping"), arg_match) >> [](int i) {
reply(atom("pong"), i);
return make_cow_tuple(atom("pong"), i);
}
);
\end{lstlisting}
......@@ -40,7 +40,7 @@ become (
self->quit();
},
on(atom("pong"), arg_match) >> [](int i) {
reply(atom("ping"), i+1);
return make_cow_tuple(atom("ping"), i+1);
}
);
\end{lstlisting}
......@@ -39,55 +39,59 @@ struct printer : sb_actor<printer> {
Note that \lstinline^sb_actor^ uses the Curiously Recurring Template Pattern. Thus, the derived class must be given as template parameter.
This technique allows \lstinline^sb_actor^ to access the \lstinline^init_state^ member of a derived class.
The following example illustrates a more advanced state-based actor that implements a stack with a fixed maximum number of elements.
Note that this example uses non-static member initialization and thus might not compile with some compilers.
\clearpage
\begin{lstlisting}
class fixed_stack : public sb_actor<fixed_stack> {
// grant access to the private init_state member
friend class sb_actor<fixed_stack>;
static constexpr size_t max_size = 10;
size_t max_size = 10;
std::vector<int> data;
vector<int> data;
behavior empty = (
on(atom("push"), arg_match) >> [=](int what) {
data.push_back(what);
become(filled);
},
on(atom("pop")) >> [=]() {
reply(atom("failure"));
}
);
behavior full;
behavior filled;
behavior empty;
behavior filled = (
on(atom("push"), arg_match) >> [=](int what) {
data.push_back(what);
if (data.size() == max_size)
become(full);
},
on(atom("pop")) >> [=]() {
reply(atom("ok"), data.back());
data.pop_back();
if (data.empty())
become(empty);
}
);
behavior& init_state = empty;
behavior full = (
on(atom("push"), arg_match) >> [=](int) { },
on(atom("pop")) >> [=]() {
reply(atom("ok"), data.back());
data.pop_back();
become(filled);
}
);
public:
fixed_stack(size_t max) : max_size(max) {
full = (
on(atom("push"), arg_match) >> [=](int) { /* discard */ },
on(atom("pop")) >> [=]() -> cow_tuple<atom_value, int> {
auto result = data.back();
data.pop_back();
become(filled);
return {atom("ok"), result};
}
);
filled = (
on(atom("push"), arg_match) >> [=](int what) {
data.push_back(what);
if (data.size() == max_size) become(full);
},
on(atom("pop")) >> [=]() -> cow_tuple<atom_value, int> {
auto result = data.back();
data.pop_back();
if (data.empty()) become(empty);
return {atom("ok"), result};
}
);
empty = (
on(atom("push"), arg_match) >> [=](int what) {
data.push_back(what);
become(filled);
},
on(atom("pop")) >> [=] {
return atom("failure");
}
);
behavior& init_state = empty;
}
};
\end{lstlisting}
......
......@@ -35,24 +35,18 @@ Choosing one or the other is merely a matter of personal preferences.
\subsection{Replying to Messages}
\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.
This identifies the sender of the received message and is used implicitly by the functions \lstinline^reply^ and \lstinline^reply_tuple^.
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.
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.
\begin{lstlisting}
void broker(const actor_ptr& master) {
void client(const actor_ptr& master) {
become (
on("foo", arg_match) >> [=](const std::string& request) {
auto hdl = make_response_handle();
sync_send(master, atom("bar"), request).then(
on("foo", arg_match) >> [=](const string& request) -> string {
return sync_send(master, atom("bar"), request).then(
on_arg_match >> [=](const std::string& response) {
reply_to(hdl, response);
return response;
}
);
}
......@@ -60,9 +54,6 @@ void broker(const actor_ptr& master) {
};
\end{lstlisting}
In any case, do never reply than more than once.
Additional (synchronous) response message will be ignored by the receiver.
\clearpage
\subsection{Chaining}
\label{Sec::Send::ChainedSend}
......
\section{Strongly Typed Actors}
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).
\ No newline at end of file
......@@ -35,7 +35,7 @@ When using synchronous messaging, \libcppa's runtime environment will send ...
\begin{itemize}
\item \lstinline^{'EXITED', uint32_t exit_reason}^ if the receiver is not alive
\item \lstinline^{'VOID'}^ if the receiver handled the message but did not call \lstinline^reply^
\item \lstinline^{'VOID'}^ if the receiver handled the message but did not respond to it
\item \lstinline^{'TIMEOUT'}^ if a message send by \lstinline^timed_sync_send^ timed out
\end{itemize}
......@@ -120,10 +120,11 @@ sync_send(testee, atom("get")).then(
);
\end{lstlisting}
\clearpage
\subsubsection{Continuations for Event-based Actors}
\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.
\begin{lstlisting}
......
......@@ -4,52 +4,27 @@
12pt,% % 12pt Schriftgröße
]{article}
%\usepackage{ifpdf}
%\usepackage[english]{babel}
% UTF8 input
\usepackage[utf8]{inputenc}
% grafics
%\usepackage{graphicx}
%\usepackage{picinpar}
% others
%\usepackage{parcolumns}
%\usepackage[font=footnotesize,format=plain,labelfont=bf]{caption}
%\usepackage{paralist}
% include required packages
\usepackage{url}
\usepackage{array}
%\usepackage{tocloft}
\usepackage{color}
\usepackage{listings}
\usepackage{xspace}
\usepackage{tabularx}
\usepackage{hyperref}
\usepackage{fancyhdr}
\usepackage{multicol}
% HTML compilation
\usepackage{hevea}
% font setup
\usepackage{cmbright}
\usepackage{txfonts}
\usepackage[scaled=.90]{helvet}
\usepackage{courier}
%\usepackage{natbib}
%\usepackage{lmodern}
%\usepackage{newcent}
%\renewcommand{\ttdefault}{lmtt}
%\usepackage{fontspec}
%\defaultfontfeatures{Mapping=tex-text} % For archaic input (e.g. convert -- to en-dash)
%\setmainfont{Times New Roman} % Computer Modern Unicode font
%\setmonofont{Anonymous Pro}
%\setsansfont{Times New Roman}
% par. settings
\parindent 0pt
......@@ -77,17 +52,16 @@ User Manual\\\normalsize{\texttt{libcppa} version 0.8}\vfill}
\date{\today}
% page setup
\setlength{\voffset}{-0.5in}
\setlength{\hoffset}{-0.5in}
\addtolength{\textwidth}{1in}
\addtolength{\textheight}{1.5in}
\setlength{\headheight}{15pt}
% some HEVEA / HTML style sheets
\newstyle{body}{width:600px;margin:auto;padding-top:20px;text-align: justify;}
% more compact itemize
\newenvironment{itemize*}%
{\begin{itemize}%
\setlength{\itemsep}{0pt}%
......@@ -95,8 +69,8 @@ User Manual\\\normalsize{\texttt{libcppa} version 0.8}\vfill}
{\end{itemize}}
\begin{document}
%\fontfamily{ptm}\selectfont
% fancy header setup
%BEGIN LATEX
\fancypagestyle{plain}{%
\fancyhf{} % clear all header and footer fields
......@@ -104,12 +78,14 @@ User Manual\\\normalsize{\texttt{libcppa} version 0.8}\vfill}
\renewcommand{\footrulewidth}{0pt}
}
%END LATEX
\maketitle
\clearpage
\pagestyle{empty}
\tableofcontents
\clearpage
% fancy header setup for page 1
%BEGIN LATEX
\setcounter{page}{1}
\pagenumbering{arabic}
......@@ -121,9 +97,7 @@ User Manual\\\normalsize{\texttt{libcppa} version 0.8}\vfill}
}
%END LATEX
%{\parskip=0mm \tableofcontents}
% basic setup for listings
% code listings setup
\lstset{%
language=C++,%
morekeywords={constexpr,nullptr,size_t,uint32_t,assert},%
......@@ -137,6 +111,7 @@ User Manual\\\normalsize{\texttt{libcppa} version 0.8}\vfill}
numberstyle=\footnotesize%
}
% content
\include{FirstSteps}
\include{CopyOnWriteTuples}
\include{PatternMatching}
......@@ -147,21 +122,13 @@ User Manual\\\normalsize{\texttt{libcppa} version 0.8}\vfill}
\include{ActorManagement}
\include{SpawningActors}
\include{MessagePriorities}
\include{StronglyTypedActors}
\include{NetworkTransparency}
\include{GroupCommunication}
\include{ActorCompanions}
\include{TypeSystem}
\include{BlockingAPI}
%\include{OpenCL}
\include{StronglyTypedActors}
\include{CommonPitfalls}
\include{Appendix}
%\clearpage
%\bibliographystyle{dinat}
%\bibliographystyle{apalike}
%\bibliography{/bib/programming,/bib/rfcs}
%\clearpage
%{\parskip=0mm \listoffigures}
%\clearpage
\end{document}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment