Actors are components of message-passing systems that are particularly popular these days. They make concurrency a lot easier to understand compared to the traditional thread-monitor-lock model.
An actor is a thread-like program that run independently from other actors. It has a mailbox to receive messages from other actors, where each message represents a task to complete. Although actors are much easier understand, we still need to pay attention on how to use them. Following is a list of golden rules when using actors:
Actors should never be blocked to wait for some result to come back. Instead of waiting, the time could be used to process other messages. Moreover, when an actor is blocked, it will lose requests/messages from other actors and the system could risk to collapse due to deadlocks. If blocking cannot be avoided, delegate to special actors that are dedicated just to the specific blocking tasks.
Communicate only via messages
The idea behind the message-passing system is to keep all the shared data within the message. If the communication doesn’t happen through messages, we risk to introduce some extra shared data that need to be protected by locks. A part from the performance loss, what’s the point of using the actor model if we still have to deal with locks?
Messages should be immutable
As mentioned before, the messages contain all the shared data between the actors. Having immutable messages guarantees that the shared data is thread-safe. This can be easily achieved by using case classes for your messages: not only the immutability is guaranteed, but pattern matching can be easily used to identify the type of your message.
Messages should be complete and self-contained
When receiving a message, an actor should have all the information needed to process it. This reduces dependencies between actors and it allows an actor not to have any memory/history of when/why a specific request was made. Don’t be scared of adding some redundancy to your messages if it helps to improve your system performance.
If you try to follow these simple rules, your concurrent challenges will be a lot easier to tackle — and the system more performant!