As I'm getting to terms with usage of Akka.actors, I came across an interesting situation where all my actor did was for a given case of message, fire a blocking call and await its reply. Setting up the context below
So after looking around a lot, I found two solutions to this problem which I'll be putting forward below.
Context
A web-service that talks to some other web-service or makes a database call. Instead of using a traditional ExecutorService, I thought I would give Akka ActorSystem a try. But for the setup I've have initially I found that making blocking calls within an Actor can not only be expensive but bring down your system as such.So after looking around a lot, I found two solutions to this problem which I'll be putting forward below.
1. For every message in the actor inbox, spin up a new child actor
Thoughts: Since actors are supposed to have very small lifespan, it makes sense to delegate a message from inbox of the actor to a new child actor which would be given the PoisonPill once its job is served. This is how it would look --
Important thing to note in the above code snippet is how I attached my own dispatcher to the inner worker actor. That is the key to make sure that the parent ActorWithinActor is not blocked when invoked by any one. Advantage with making inner worker directly respond back to the original sender is that parent Actor can simply fire-n-forget!
Important thing to note in the above code snippet is how I attached my own dispatcher to the inner worker actor. That is the key to make sure that the parent ActorWithinActor is not blocked when invoked by any one. Advantage with making inner worker directly respond back to the original sender is that parent Actor can simply fire-n-forget!
2. Wrap the blocking call within Futures
Thoughts: This is most common pattern I came across as was suggested on many websites and blogs. Since the ask(), which is used to send messages to actors can receive a future, we can therefore wrap our blocking calls within futures and process the result of that blocking call in the onCompleted or onSuccess method of the future. This is how it would look --
Important thing is you here is first make a copy of original sender so that you don't loose the context of it. Obvious thing to do now would be have a pool of such actor and use a Router to route messages to them.
Hope you find this article useful. If you know better way of handling blocking calls within Actors, do mention in the comments below. I'm interested to know!
Hope you find this article useful. If you know better way of handling blocking calls within Actors, do mention in the comments below. I'm interested to know!
No comments:
Post a Comment