The Actor Model is one of the most interesting models I’ve seen so far. It’s designed for high concurrency, scalability and fault tolerance. Most programming languages have a framework that implements it, but some programming languages like Erlang/Elixir are designed with this model in mind.
History
The actor model was created in 1973, inspired by physics and some programming languages like Smalltalk, Lisp and others. It was designed to handle highly parallel computer machines consisting of dozens, hundreds, or even thousands of independent microprocessors, each with its own local memory and communications processor, communicating via a high-performance communications network.
Fundamentals concepts
In Object-Oriented Programming, we treat everything as an object, in the actor model we treat everything as an actor.
Actor
It treats the actor as a basic block of concurrency, where an actor reacts to a message, by changing your states, modifying our behaviour for the next message, and sending more messages. In other words, an actor can:
- Send a finite number of messages to other actors
- Create a finite number of new actors
- Designate the behaviour to be used for the next message it receives.
Message
Message is a unit of communication between actors, a message should be serializable and be transmitted over networks.
Mailbox
The mailbox is how an actor reads messages, every message it receives goes to a mailbox, typically Actor Sysmte uses FIFO(First-In First-Out) but depending on the case, we can implement a Mailbox using a different approach if you need, for example, to prioritize a message over other
State
State it’s the actor state, it can be read from other actors, but only the actor itself can modify your state.
Behaviours
The behaviour is how an actor will react to a message.
PID/Actor Reference
Process Identification (PID) or Actor Reference it’s the actor’s address, with this address an actor can send a message to another actor, this address can be local or on the remote machine.
Supervision
Supervision is how the Actor Model coordinates your tasks and ensures resilience.
So imagine, you create an actor and you ask to that actor do an action and fails to do it, how are you going to handle this failure? Should you retry? Should you stop the all process? Should you stop only that actor?
When the actor fails it’ll emit a signal to the supervisor and it decides what to do, stop only that actor, stop all actors or send the signal to its supervisor and let the layer above define what to do.
All actors are supervisors.
Virtual Actor/Grain
The virtual actor is a concept created by Microsoft on the Orleans project where you don’t need to know the Actor ID, you will have a unique identifier and the actor framework will find the corresponding actor (or create a new one if case it doesn’t find it).
Virtual Actor seems to fit very well with DDD and event source, where you can use the Actor ID as the Domain ID, and the message you received you can store in some database, so when you load the domain you can easily reply to all message to get the current state (or save the state as a snapshot).
Framework
The framework to use the Actor Model will depend on the programming language, I can only talk about it for C#
Microsoft Orleans
Akka
Proto.Actor
Elixir/Erlang
Elixir/Erlang is based on BEAM VM, which is based on the Actor Model, so you won’t need any framework. Because the Virtual Actor model is a kind of new concept Elixir doesn’t have native support for it, so you need to use an external library. I highly recommend you study about them
Conclusion
The actor model is very interesting, if you are also interested in it I recommend that you look deep. We use the actor model to create high-scale applications and it can be combined with Domain-Driven Design, Event Source and CQRS, in the next article I’ll show can we can combine them.