How to get a promise (or future) by asking Akka Actor, believing that the result is NOT available as a response from the same message

I follow this guide: http://doc.akka.io/docs/akka/2.0/intro/getting-started-first-scala.html

Basically, there is a master actor who responds to these two messages:

def receive = { case Calculate => { //.... } case Result(value) => { //.... } } 

We send the message “Calculate” and after several “Results” (from subordinate actors) we have the correct calculation

Now I'm inside the action of the play2 controller, and I use this:

 val promise = (master ? Calculate)(10.seconds).mapTo[String].asPromise 

Unfortunately (obviously), I am not receiving anything, because the Calculate message responds with a message to the sender.

I would like to somehow make Akka Actor wait ... and when the calculation is complete, to send a message back to the sender.

But how? ... If I do not model it wrong!

+4
source share
2 answers

You must either forward send the message to the slaves (which store the same sender), or include the sender in the message to the slaves. For instance:

 def receive = { case Calculate => slave ! CalculateWithSender(sender) case res @ Result(value, originalSender) => val result = resultMap(originalSender) + res // assuming results are just added resultMap += (originalSender -> result) if (resultsAreFinished(originalSender)) originalSender ! result } 

or

 def receive = { case Calculate => slave.forward(Calculate) case res @ Result(value, originalSender) => val result = resultMap(originalSender) + res // assuming results are just added resultMap += (originalSender -> result) if (resultsAreFinished(originalSender)) originalSender ! result } 

or

 def receive = { case Calculate => slave.tell(Calculate, sender) case res @ Result(value, originalSender) => val result = resultMap(originalSender) + res // assuming results are just added resultMap += (originalSender -> result) if (resultsAreFinished(originalSender)) originalSender ! result } 

I am not familiar with Play promises, but ? ( ask ) returns Akka Future . If .asPromise converts Akka Future to Play Promise , then you install.

+3
source

Adjust the new actor for each calculation. forward the message Calculate to the new player. The new member stores the original sender. When the result is ready, the result will be sent to the original sender, and the ephemeral actor will die:

 class CalculateActor extends Actor { var origSender : ActorRef = _ def receive { case Calculate => { origSender = sender slaveActors ! doStuff //.... } case Result(value) => { if(results are ready) { origSender ! results self ! PoisonPill // I'm done, time to die } } } class MasterActor extends Actor { def receive { case msg @ Calculate => { // forward sends without changing the sender context.actorOf(Props(new CalculateActor)).forward(msg) } } } 
+1
source

Source: https://habr.com/ru/post/1438027/


All Articles