I'm learning Scala and its Actors (via Akka lib) approach for handling concurrency. I'm having some questions while trying to convert typical OOP (think - Java style OOP) scenarios to Actor based ones.
Let's consider the overused e-commerce example Webstore where Customers are making Orders that contain Items. If it is simulated in OOP-style you end up with appropriately named domain model classes that interact between themselves by calling methods on each other.
If we want to simulate concurrency e.g. many customers buying items at once we throw in some sort of threading (e.g. via ExecutorService). Basically each Customer then implements Runnable interface and its run() method calls e.g. shop.buy(this, item, amount). Since we want to avoid data corruption caused by many threads possibly modifying shared data at once, we have to use synchronization. So the most typical thing to do is synchronize the shop.buy() method.
Now let's move on to Actor based approach. What I understand is that Shop and each Customer now become Actors who, instead of calling buy() method on shop directly, sends message to shop. But here come the difficulties.
Answering your questions:
2) Your domain model (including shops, orders, buyers, sellers, items) should be described with immutable case classes. Actors should exchange (immutable) commands, which may use these classes, like AddItem(count: Int, i: Item)
- AddItem
case class represents command and encapsulates business entity called Item
.
1) Your protocol, e.g. interaction between shops, orders, sellers, buyers etc., should be encapsulated inside actor (one actor class per protocol, one instance per state). Simply saying, an actor should manage any (mutable) state, changing between requests, like current basket/order. For instance, you may have actor for every basket, which will contain information about choosed items and receive commands like AddItem
, RemoveItem
, ExecuteOrder
. So you don't need actor for every business entity, you need actor for every business process.
In addition, there is some best practices and also recommendations about managing concurrency with routers.
P.S. The nearest JavaEE-based approach is EJB with its entities (as case-classes) and message-driven beans (as actors).