Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execution context for futures in Actors

I have a Actor, and on some message I'm running some method which returns Future.

 def receive: Receive = {

    case SimpleMessge() =>
        val futData:Future[Int] = ...
        futData.map { data =>
           ... 
        }
}

Is it possible to pass actual context to wait for this data? Or Await is the best I can do if I need this data in SimpleMessage?

like image 631
Michał Jurczuk Avatar asked Jun 13 '14 15:06

Michał Jurczuk


Video Answer


1 Answers

If you really need to wait for the future to complete before processing the next message, you can try something like this:

object SimpleMessageHandler{
  case class SimpleMessage()
  case class FinishSimpleMessage(i:Int)
}

class SimpleMessageHandler extends Actor with Stash{
  import SimpleMessageHandler._
  import context._
  import akka.pattern.pipe

  def receive = waitingForMessage
  def waitingForMessage: Receive = {

    case SimpleMessage() =>
      val futData:Future[Int] = ...
      futData.map(FinishSimpleMessage(_)) pipeTo self
      context.become(waitingToFinish(sender))
  }

  def waitingToFinish(originalSender:ActorRef):Receive = {
    case SimpleMessage() => stash()

    case FinishSimpleMessage(i) =>
      //Do whatever you need to do to finish here
      ...
      unstashAll()
      context.become(waitingForMessage)

    case Status.Failure(ex) =>
      //log error here
      unstashAll()
      context.become(waitingForMessage)      
  }
}

In this approach, we process a SimpleMessage and then switch handling logic to stash all subsequent SimpleMessages received until we get a result from the future. When we get a result, failure or not, we unstash all of the other SimpleMessages we have received while waiting for the future and go on our merry way.

This actor just toggles back and forth between two states and that allows you to only fully process one SimpleMessage at a time without needing to block on the Future.

like image 58
cmbaxter Avatar answered Sep 19 '22 13:09

cmbaxter