Actor model to control access of external resources


(Fabio) #1

I’ve been studying actor model and I’m trying to get some real usage examples. One thing I can think of it is using it to control concurrent access of specific resources.

Let’s imagine a banking system where each checking account is modeled as an actor. The checking account actors can be spread among various machines, forming a cluster (making use of the location transparency and features like akka-cluster). Each transaction (credit or debit) must be handled one by one so we can guarantee that the final balance is consistent. The mailbox of the actor seems to me a good place to achieve this concurrent control, so each transaction can be queued and processed properly. During each transaction processing, the actor insert new records in the database to persist the operation. In this case, the actor works as a facade / queue to the repository.

I know that an actor can handle the concurrent access of its internal state, but this concept can be correctly used to control access of external resources like databases? Is this a common approach when building this kind of application?

Thank you

(Renato) #2

Hi @fabiogouw ,

You can do it with actors for sure. You must, however, give the necessary attention to calling blocking APIs from inside an Actor. Typically, you will make sure that those blocking APIs are run on a dedicated thread pool. You will also need stash commands and make sure, for instance, that a withdraw won’t happen while another is in-flight.

It turns out that there is already that in place for you. It’s called Akka Persistence. There are different plugin implementations, the two most popular being the akka-persistence-cassandra and akka-persistence-jdbc.

The plugin will take care of calls to underlying blocking APIs and the stashing for you. However, it will do it using event sourcing. Akka Persistence is about persisting of actor state using event sourcing.

For the particular case of a bank account, event sourcing that makes a lot of sense, because you want to keep track of all deposits and withdraws. This will give you a perfect transaction log.

If you want to have CRUD based persistence then you have to take care of the blocking and stashing yourself.



(Fabio) #3

@renato , thanks for your answer! Do you know any documented use case or scenario (maybe an article on Medium, for example) that use actor in the concept I asked? I’d like to know more details of it.

(Rob Crawford) #4

I’ve used actors to represent scales (for weighing produce); each scale can only be used by one person at a time. The actor backing the UI messages the scale, asking to reserve it. If the scale’s not in use, it replies with a “go-ahead”; if it’s already in use, it declines the request.

The physical scales send messages when the weight reading changes, and those messages are delivered to the scale actors, which forward the weight changes along to the reserving user.

When the user is finished, they send a message releasing the scale.

If there are no weight changes in a certain time period (implemented with inactivity timer), the user gets a message warning them they’ll lose their reservation; if there’s still no activity, then the session is cancelled and the scale is available for another user.