I am using Akka HTTP and have a AnswerActor, I want to do following thing.
class AnswerActor() extends Actor {
var requestMap = mutable.Map[String, ActorRef]()
...
override def receive: Receive = {
// I want to store sender() here instead of reply in this case, because my reply is not available at this moment
case message: M1 => requestMap.put(sender().path.name -> sender())
// I want to reply when I receive M2, my reply is available now
case message: M2 => requestMap.get(...) ! MyReply
I use val ans = Await.result(questionActor ? M1)
, and another actor to send message M2
to AnswerActor
but there is no reply, only if I add some reply in following(case M1) it could work
case message: M1 => requestMap.put(name -> sender())
sender() ! something
Is it possible to implement the logic above in akka?
What I suspect, from your limited description, is that M2
is not being received by questionActor
after it receives M1
(or at least it's not being received soon enough after for the ask to timeout). In general there is no guarantee that a message sent from actor A to actor B will be received before a message sent from actor C to actor B, regardless of whether C sent the message before or after A (the ordering guarantee is that if actor A sends messages 1 then 2 then 3 to actor B, 3 will not be received before 1 or 2 is received and 2 will not be received before 1 is received).
In general, it's not a good idea to use Await
in an actor or in a stream, since that prevents the actor from processing any message. Within an actor, it's better to use the pipe pattern:
import akka.pattern.pipe
(questionActor ? M1).pipeTo(context.self)
If you wanted to ignore (or stash) every message besides MyReply
, you could then immediately use context.become
to install a new message handler which ignores/stashes as desired.
Within a stream, it's generally best to use the mapAsync
or, in some cases (Akka 2.6.x only) ask
stream stage to perform the ask in a non-blocking way.
The use of Await.result
may also directly be causing your problem, depending on how many cores/vCPUs are available and the Akka version: the blocking may prevent any actor or stream stage from getting CPU time.