scalaakkaakka-actor

Is it possible to get the value from a method that returns a value, when called inside an actor?


I have an actor defined like this

class RandomActor @Inject() (
                             accounts: models.Accounts
                             )extends Actor with ActorLogging{
  override def receive: Receive = {
    case Create(address, username, type, password) => {
      accounts.Service.create(address, username, type, password)
    }
  }
}

Accounts is a model class with an object called Service which has the create method. This create method returns a Future[String]. So when I'm trying to call this create method from an actor, is it possible to return the Future[String] from the actor as a message which can be stored into a variable outside an actor?


Solution

  • There seem to be two questions here: How to generate a message from a Future and how to get a message "out" of the actor system.

    The answer to the first question is to use onComplete on the Future:

     accounts.Service.create(address, username, type, password).onComplete{
       case Success(account) =>
         otherActor ! AccountCreated(account)
       case Failure(e) =>
         otherActor ! CreateAccountFailed(address, username, type)
     }
    

    This will send the appropriate message when the Future completes (either successfully or with an error).

    The answer to the second question is to use the ask pattern that allows a message to be sent to an actor from outside the actor system and a reply received:

    (RandomActor ? RequestMessage).mapTo[ReplyType].onComplete {
      case Success(reply) =>
        // process reply
      case Failure(e) =>
        // process error
    }
    

    Note that the answer will appear asynchronously on a separate thread, so care is needed when processing this sort of reply. See here for more details on ask.