The Actor Model is a very dynamic form of dataflow where nodes and arcs can come and go based on run-time demands.
It is a concurrent model of computation developed by Carl Hewitt that is also similar to Object Oriented Programming (OOP). The Actor Model is actually closer to the original definition of OOP than most current OO languages. Alan Kay, the creator of OOP, commented on a blog post...
"Many of Carl Hewitt's Actors ideas... were more in the spirit of OOP than the subsequent Smalltalks." From Moti asks: Objects Never? Well, Hardly Ever!"
Mr. Kay defines OOP to be...
"...only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things." Dr. Alan Kay on the Meaning of Object-Oriented Programming"
Overview of the Actor Model
The Actor Model uses message passing to send data directly to a single actor asynchronously. Every actor has a unique address to determine which actor should receive what message. A mailbox (an ordered queue) stores received messages in the actor.
Messages can be taken from the mailbox in any order. In most implementations, actors have a message processing procedure that will pattern match on the messages, similar to a case or switch statement, and pass the messages to the appropriate methods of the actors. If the message is unknown, then it is either silently discarded or creates an error depending on the implementation.
Actors can only send messages to other actors that they know about (i.e. actors they have addresses to). It could be an address that was sent in a message or an address of an actor it created.
Message delivery is not guaranteed. At most, messages are delivered once and possibly never get delivered. To ensure that a message reaches its destination you have to use an acknowledgment protocol between the two actors.
Like all types of dataflow, receiving a message triggers the activation of an actor. Execution happens concurrently.
Actors are referentially transparent (functional) per invocation. They can change their internal state but it does not take effect until the next activation. Effectively they pass their state out and back to themselves so that the next activation uses the updated state.
Local data is encapsulated inside actors. The only way to communicate with them is through messages. Internal data can not leak out unless it is specifically sent to other actors.
Comparison to Object Oriented Programming
The Actor Model is similar to OOP except the methods do not return a value. Instead they send messages to return values.
A message is a form of indirect call. An actor never directly calls methods in other actors. In fact, they couldn't even if they wanted to.
By removing direct calls, actors are able to work concurrently with other actors, essentially asynchronous objects.
Like objects, actors retain local state and can be created.
Relation to Dataflow
The Actor Model is different from most other dataflow models where data is transmitted over arcs. We can say that the Actor Model is just dynamic dataflow where the arcs have a capacity of one and are created immediately before sending the data and then disconnected immediately afterwards.
It is an asynchronous dataflow model that has functional nodes but passes state from one activation to the next to simulate stateful nodes.
Since everything is an actor, compound nodes are easily created by defining actors in terms of other actors.
- Asynchronous activations
- Dynamic program structure
- Pushed Data
- Arc joins and splits are not allowed... technically arcs do not exist in this model
- Data (messages) are immutable
- Functional nodes but passes state from one activation to the next to simulate stateful nodes
- Multiple inputs are simulated by allowing different messages to be received on one input
- Multiple outputs are simulated by actors directly sending data to multiple receivers. Other actors are not allowed to explicitly connect to these outputs
- Since there is only one input, actors don't need the concept of fire patterns. They activate whenever there are messages available.
- Cycles are allowed
- Recursion poses no problems since every actor is distinct from all others
- Compound nodes are allowed
- Arc capacity: While there are no arcs in the Actor Model, we can imagine arcs being dynamically created for each messages that needs to be transmitted. In this case arcs would have a capacity of one.
- Multi-rate token production and consumption: There are no limits to the amount of messages that an actor can send in one activation. Only one message may be received per activation.
Where is the Actor Model Used?
The Actor model is a very dynamic and fluid dataflow model. It is beneficial anytime applications need to change due to runtime demands such as:
- Systems where you can't determine how the nodes should be connected until runtime.
- Systems where nodes need to be created dynamically based on some runtime factor. For example creating a node for every new connection on a web server.
- Systems where services can be added or removed from an application at runtime.
Where is it Not Used?
In situations where the program is essentially static, the dynamism of the Actor Model gets in the way. For example, a fixed pipeline of transformations or circuit simulations.
To some applications, the connections between nodes are as important as the nodes themselves. When you need to ensure that nodes can be freely reused simply by changing the connections to the nodes, the Actor Model is a poor fit.
This is an excerpt from the book "Dataflow and Reactive Programming Systems"