20
votes

I'm not quite sure how actors can be used to access the database. In the documentation and books for Akka this topic seems to be omitted.

One solution can be a wrapped DAO in an stateless actor. For example for each table (or domain object type or aggregate type) in the database one can create an actor which is responsible for all CRUD operations. A variation of this can be a separation of commands and queries. For example for each data type 1 command actor (for concurrency) and 10 query actors (for parallelism).

An other approach could be to create stateful actors representing exactly one row (or domain object instance or aggregate instance) in the database. Of course the database can be in this case also an event store (like the akka persistence module) with an eventually consistent projection to a database, document store or a cache. That's not relevant here. This approach is actually an implementation of an in memory cache with all benefits and problems. There must be a strategy for destroying actors to not run out of memory after a while.


I will extend my question for DDD:

Let's say, I want to develop a DDD application with Akka actors. Let's concentrate here on the command part. In my opinion this should be implemented in this way: For each bounded context there will be a port actor, e.g. Spray REST API, that routes messages to the appropriate domain service actor. This service actor coordinates a business task to one or more domain model aggregates. Each single aggregate is a stateful actor that is restored (or created on new data) by the service actor from database. The service actor sends/routes messages to all involved aggregate actors. The receiving domain model actors will perform business validation on their state + message and then they write their changes to the database, e.g. Slick DAOs. After sending a done back to the service actor they get stopped. When all aggregate actors are finished a done message is send back to the sender of the message. A variation could be to not stop the stateful domain model actors immediately but after a time span, say 3 minutes.

Is this a valid usage pattern for DDD with Akka?

1
I don't understand why this gets close votes. I've also always found data access to be a hazy/not well documented subject in Actor Model platforms. I think (but haven't tested) that an Event Sourcing approach would blend well with the actor stuff since actor messages are immutable. An Aggregate would send a message to the world (i.e, a dispatching actor) containing its new state. Then a persistence actor would be responsible for appending this new state to the event store. Other actors could act based on that message on an ad hoc basis.guillaume31
Event Sourcing is actually already a build-in feature in Akka. I haven't tested it yet because I'm new to Akka and it's a complexity booster for me. See doc.akka.io/docs/akka/snapshot/scala/persistence.htmlSebastian
To my future me: Remember to read the book Reactive Enterprise with Actor Model: Application and Integration Patterns for Scala and Akka by Vaughn Vernon spring 2015 AmazonSebastian

1 Answers

7
votes

Usually DB reading operations (cRud) can be performed directly by any actor. There is no need to make any special handling in most cases. Just a simple round-robin to balance the load.

As for update operations (CrUD), they can be split into non intersecting domains/shards. For instance, all operations with a single account should be preferably processed by a single actor. One may have N almost independent processing actors and a router that routes commands to one of them based on account.hashCode % N, for instance. Thus operations will be distributed between actors more or less evenly and every account will be processed sequentially.

P.S. Slick seems to be a descent db library for Akka applications.