After going through the previous blogs, we are now familiar with Akka, Actors, and their implementation (implementing-actors-in-akka). In this blog, we are going to discuss the Ask Pattern in Akka. So, let’s begin.
Communication Among Actors
In Akka, actors communicate with each other by sending and receiving messages. The messages can be sent in many patterns like-
- Fire and Forget –The tell() method works on the “fire-forget” approach. In this, we just send the message and do not wait or care about the response. It means there is no way to know if the message was received, the processing succeeded or failed. We can also use “!” (exclamation mark) to send a message. This is the preferred way of sending messages as it gives the best concurrency and scalability characteristics.
- Request and Response – In this we send the message and wait for the response. It is a frequently used pattern in Akka. This is done using Timeout.
To implement Timeout , we create one-off Actor with scheduled Timeout.
- Create a one-off Actor and schedule a timeout message to itself.
- Either forward the response or send Failure holding a timeout exception.
Interacting with Actors from the outside – If we send a message to an Actor from the outside then-
- There is no implicit sender.
- Responses go to dead letters.
val someActor = system.actorOf(...) someActor ! SomeRequest(...)
As this is not an actor, responses go to dead letters.
When a message is sent to an Actor that is terminated before receiving the message, it will be sent as a DeadLetter to the ActorSystem’s EventStream.
When this message was sent without a sender
sender will be
So, to overcome the issues of the request-response pattern, we use the Ask Pattern.
What is ASK PATTERN?
In Akka, ask is a pattern and involves Actors as well as Futures. Ask is used to sends a message asynchronously and it returns a Future which represents a possible reply. If the actor does not reply and complete the future, it will expire after the timeout period. After the timeout period, it throws a TimeoutException.
Using The Ask Pattern
- It is represented either by “?” (question mark) or ask() method.
- ask() returns a Future which gets completed with the response or an AskTimeoutException.
- For this to work, we need to import akka.pattern.ask.
- We also need an explicit Timeout and ExecutionContext in scope.
Combining Ask and PipeTo Patterns
The other pattern which can be used is PipeTo pattern. For this to work, we need to import akka.pattern.pipe.
testActor ? TestMessage pipeTo self
If we want to send the result of a Future to an Actor, pipeTo is used.
- Either the successful result of the Future is sent to the given Actor or
- a Status.Failure holding the failure is sent.
Ask Pattern: Do’s and Don’ts
- In non-actor code, use ask to interact with actor code if we care about the response else we can simply use tell().
- But in actor code, only use ask in combination with pipeTo to preserve the single-threaded illusion.
- In both cases, we have to know a Timeout.
- Don’t ever register callbacks on a Future or some sort of other concurrent code accessing mutable actor state so as to maintain the single-threaded illusion.
So, this is all about Ask Pattern. Stay tuned for more upcoming blogs on Akka.