Cloud-Native Engineering with the Actor Model
Is the Actor Model fixing concurrent Object-Oriented Programming?
What Architecture paradigms are good for Cloud-Edge engineering?
We originally posted this article on LinkedIn.
Evolution of Programming languages is all about abstractions : the closer to human languages, the better.
Object-Oriented Programming was a big step forward to get better software design and improved code quality. It helped a lot with reasoning about complex systems.
But at the same time, it introduced a lot of new burdens : when to use design patterns or anti-patterns? UML or not UML ? Composition versus inheritance ?
With experience, any developer can find her/his way and will take decisions that will be good enough and that will anyway very likely be refactored and improved in the next iteration.
I remember spending days with my team designing a class inheritance diagram for one of our domain models. That was at the beginning of my career and even though we already tried to be an Agile team, we believed it was worth it.
Nowadays, unless I’m working on a library that I have refactored already a couple of times, I never work on a complex inheritance design. I start with simple objects, implement them, and favor composition over inheritance. I usually end-up with an object graph that will be refactored a couple of times and in which I might slowly introduce inheritance.
But there is always a bigger issue with any object-graph : concurrency.
And I think it’s actually a general problem of OOP.
Software classes are often designed as abstractions of real objects.
A class car could have a member engine and provide methods like startEngine or stopEngine. They modify the internal state of the car object. In concurrent programming, we must ensure that different threads are not calling different methods modifying internal state at the same time. Like one thread calling startEngine while the other one is calling stopEngine in parallel. That can lead to pretty bad consequences.
Originally, OOP was not really designed with concurrency in mind.
But today, concurrency is everywhere and platforms like the JVM have provided many tools to ensure multi-threading. These tools have dramatically improved over time.
We started with synchronized two decades ago and have now full-fledged concurrent libraries. However, it does not fix the root cause, OOP on the JVM is not designed for concurrency.
The Actor Model, invented by Car Ewitt in the 1970’s is addressing that problem with a very theoretical approach. A Software Actor is an Object that reacts to messages. Messages are queued and are executed one after another.
That introduces the concept of single thread illusion : actors can run on multiple threads and multiple machines (Cloud-Native!) and send messages to each other, but from an actor point of view, messages will be executed one after the other.
Akka is a brilliant implementation of the Actor Model and provides a huge set of tools and helpers to build up actor-graphs with millions of actors just working together very smoothly and super efficiently.
We have been designing software with Akka and the Actor Model for more than 10 years and it seems to us that we will design most of our next high-demanding applications using the Actor Model.
Instead of thinking in terms of objects and methods we think in terms of Actors and sending messages. It also feels very natural. Many complex systems, like biological systems, have interactions that seem like sending messages (think about cells' interactions for instance, is not a lot like actor objects sending messages?).