-
Notifications
You must be signed in to change notification settings - Fork 2
/
Introduction.tex
85 lines (58 loc) · 6.08 KB
/
Introduction.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
\section{Introduction}
Before diving into the API of \lib, we discuss the concepts behind it and explain the terminology used in this manual.
\subsection{Actor Model}
The actor model describes concurrent entities---actors---that do not share state and communicate only via asynchronous message passing.
Decoupling concurrently running software components via message passing avoids race conditions by design.
Actors can create---spawn---new actors and monitor each other to build fault-tolerant, hierarchical systems.
Since message passing is network transparent, the actor model applies to both concurrency and distribution.
Implementing applications on top of low-level primitives such as mutexes and semaphores has proven challenging and error-prone.
In particular when trying to implement applications that scale up to many CPU cores.
Queueing, starvation, priority inversion, and false sharing are only a few of the issues that can decrease performance significantly in mutex-based concurrency models.
In the extreme, an application written with the standard toolkit can run slower when adding more cores.
The actor model has gained momentum over the last decade due to its high level of abstraction and its ability to scale dynamically from one core to many cores and from one node to many nodes.
However, the actor model has not yet been widely adopted in the native programming domain.
With \lib, we contribute a library for actor programming in C++ as open-source software to ease native development of concurrent as well as distributed systems.
In this regard, \lib follows the C++ philosophy ``building the highest abstraction possible without sacrificing performance''.
\subsection{Terminology}
\lib is inspired by other implementations based on the actor model such as Erlang or Akka. It aims to provide a modern C++ API allowing for type-safe as well as dynamically typed messaging.
While there are similarities to other implementations, we made many different design decisions that lead to slight differences when comparing \lib to other actor frameworks.
\subsubsection{Dynamically Typed Actor}
A dynamically typed actor accepts any kind of message and dispatches on its content dynamically at the receiver.
This is the ``traditional'' messaging style found in implementations like Erlang or Akka.
The upside of this approach is (usually) faster prototyping and less code.
This comes at the cost of requiring excessive testing.
\subsubsection{Statically Typed Actor}
\lib achieves static type-checking for actors by defining abstract messaging interfaces.
Since interfaces define both input and output types, CAF is able to verify messaging protocols statically.
The upside of this approach is much higher robustness to code changes and fewer possible runtime errors.
This comes at an increase in required source code, as developers have to define and use messaging interfaces.
\subsubsection{Actor References}
\label{actor-reference}
\lib uses reference counting for actors. The three ways to store a reference to an actor are addresses, handles, and pointers. Note that \emph{address} does not refer to a \emph{memory region} in this context.
\paragraph{Address}
\label{actor-address}
Each actor has a (network-wide) unique logical address. This identifier is represented by \lstinline^actor_addr^, which allows to identify and monitor an actor.
Unlike other actor frameworks, \lib does \emph{not} allow users to send messages to addresses.
This limitation is due to the fact that the address does not contain any type information.
Hence, it would not be safe to send it a message, because the receiving actor might use a statically typed interface that does not accept the given message. Because an \lstinline^actor_addr^ fills the role of an identifier, it has \emph{weak reference semantics} \see{reference-counting}.
\paragraph{Handle}
\label{actor-handle}
An actor handle contains the address of an actor along with its type information and is required for sending messages to actors. The distinction between handles and addresses---which is unique to \lib when comparing it to other actor systems---is a consequence of the design decision to enforce static type checking for all messages. Dynamically typed actors use \lstinline^actor^ handles, while statically typed actors use \lstinline^typed_actor<...>^ handles. Both types have \emph{strong reference semantics} \see{reference-counting}.
\paragraph{Pointer}
\label{actor-pointer}
In a few instances, \lib uses \lstinline^strong_actor_ptr^ to refer to an actor using \emph{strong reference semantics} \see{reference-counting} without knowing the proper handle type. Pointers must be converted to a handle via \lstinline^actor_cast^ \see{actor-cast} prior to sending messages. A \lstinline^strong_actor_ptr^ can be \emph{null}.
\subsubsection{Spawning}
``Spawning'' an actor means to create and run a new actor.
\subsubsection{Monitor}
\label{monitor}
A monitored actor sends a down message~\see{down-message} to all actors monitoring it as part of its termination.
This allows actors to supervise other actors and to take actions when one of the supervised actors fails, i.e., terminates with a non-normal exit reason.
\subsubsection{Link}
\label{link}
A link is a bidirectional connection between two actors.
Each actor sends an exit message~\see{exit-message} to all of its links as part of its termination.
Unlike down messages, exit messages cause the receiving actor to terminate as well when receiving a non-normal exit reason per default.
This allows developers to create a set of actors with the guarantee that either all or no actors are alive.
Actors can override the default handler to implement error recovery strategies.
\subsection{Experimental Features}
Sections that discuss experimental features are highlighted with \experimental. The API of such features is not stable. This means even minor updates to \lib can come with breaking changes to the API or even remove a feature completely. However, we encourage developers to extensively test such features and to start discussions to uncover flaws, report bugs, or tweaking the API in order to improve a feature or streamline it to cover certain use cases.