The call of the Future inside the method of receiving and stopping the actor after this

I create a group of actors who do some work, and then they stop. In some of these participants, I call third-party APIs that return Future .

 MyActor extends Actor { .... def receive = { case MsgA => { ... //this evaluates to a Future val p : Future = someFutureAPICall() //stop the actor context stop self } } } 

Now that Future does not block, the actor will be stopped immediately after that (?), Even if Future not completed. What is the expected behavior in this case?

For example, if I have onComplete on Future , will it ever be done, even if the actor stopped?

 MyActor extends Actor { .... def receive = { case MsgA => { ... //this evaluates to a Future val p : Future = someFutureAPICall() p.onComplete { //will these expressions ever be evaluated ? case Success(x) => log.info("Success") case Failure(f) => log.info("Failure") } //stop the actor context stop self } } } 
+7
scala future actor akka
source share
1 answer

Yes, code that returns the future (third-party APIs) will be immediately executed and return an unfinished future.

The fulfillment of this Future to the fullest has nothing to do with the actor who began to live it.

If you no longer need this actor, you do not need to wait for the completion of the "Future", and you can stop the actor, as you do in the first example.

If you need to do something in this actor, as a result of this future, you can set the onComplete callback for this future. Once the future is complete, he can send a message to the actor to stop. For example, for example:

 val myActor = self // Don't close over unstable actor reference by using self directly p.onComplete { case Success(x) => myActor ! x; myActor ! akka.actor.PoisonPill // sends result to be processed and then stops actor case Failure(f) => myActor ! akka.actor.PoisonPill // stops actor } 

EDIT

Another alternative suggested in the comments is to use a pipeTo usage pipeTo . It is almost the same. Here's how it is implemented in the Akka library:

 def pipeTo(recipient: ActorRef)(implicit sender: ActorRef = Actor.noSender): Future[T] = { future onComplete { case Success(r) β‡’ recipient ! r case Failure(f) β‡’ recipient ! Status.Failure(f) } future } 

Here's how you can call it after creating the Future:

 p pipeTo myActor 

The main difference is that your actor will have to disconnect after receiving messages, and an error message is reported to the actor with the message Failure . This method is a little safer to use, because you need to pass an ActorRef , and you do not need to store it (self) in a variable.

+8
source share

All Articles