0
votes

say, I have an Actor whose receive function likes

def receive = {
  case Message =>
    val doFuture: Future[String] = doSomething()

    doFuture onSuccess {
      case doResult =>
        //////////// Here is the problem !! /////////////
        // --> here fail. Seems sender cannot send back the result to the caller
        sender ! doResult
    }

    doFuture onFailure {
      // handle exception
    }
}

why the sender cannot send back message any more ?

2
You're closing over the sender (which is mutable). By the time the future is done, the sender isn't necessarily valid / the same anymore. See stackoverflow.com/questions/16898131/sender-inside-a-futureChristophe Vanfleteren
make sure the future executes in Actors execution context by adding import context.dispatchersarveshseri
Thanks! And sorry for the duplicate question..hliu

2 Answers

2
votes
def receive = {
  case Message =>
    val doFuture: Future[String] = doSomething()
    val requester = sender

    doFuture onSuccess {
      case doResult =>
        requester ! doResult
    }

    doFuture onFailure {
      // handle exception
    }
}

You can save your original sender and then use it (in case if you don't want to use pipe for some reason). Anyway, pipe looks much better and is specially designed for such cases:

import akka.pattern.pipe

 def receive = {
      case Message =>
          val doFuture: Future[String] = doSomething()  
          doFuture pipeTo sender
 }
2
votes

This is what pipeTo is for:

import akka.pattern.pipe

...

doFuture.pipeTo(sender())