LondonMassive
LondonMassive

Reputation: 457

Wait N seconds for actor to return in Scala

I am working on a project that uses Akka actors to handle some backend processes. I have created a method that calls the Actor, however it does not return instantly. Therefore, I want a timeout of 5 seconds, so if the Actor returns within the 5 seconds, my method will return this, if not, then a default value will be returned.

Just to be clear, the method calling the Actor's method is not itself within another actor, it is just a regular class. Secondly, I have tried using Timeout and Await, and even when importing them, it says they are not found.

Example code:

service.scala

override def foo(): MyType = {
      var toReturn = MyType(fale, None, None)
      implicit val timeout: Timeout = 5.seconds
      val result = Await.result(myActor ? fetchData, timeout.duration).asInstanceOf[MyType]
      if(result.healthy == true){
          toReturn = result
      }
      toReturn     
  }

actorClass.scala

override def receive: Receive = {
    case fetchData => 
      actorFoo()
    case _ =>
      logger.error("...")
  }

...

private def actorFoo(): MyType = {
    val num1 = list1.size
    val num2 = list2.size
    val data = MyType(true, Some(num1), Some(num2))
    println(data)
    data
  }

When I run this code, the data is printed within the actorFoo method, but then nothing happens after. I even tried printing "SUCCESS" after the Await to ensure it has not broken, but even that is not printed.

Upvotes: 0

Views: 175

Answers (1)

Levi Ramsey
Levi Ramsey

Reputation: 20591

The ask pattern requires a reply to be sent, and your actor doesn't send a reply:

override def receive: Receive = {
    case fetchData => 
      actorFoo()
    case _ =>
      logger.error("...")
  }


private def actorFoo(): MyType = {
    val num1 = list1.size
    val num2 = list2.size
    val data = MyType(true, Some(num1), Some(num2))
    println(data)
    data
  }

actorFoo() has a result type of MyType, but the result gets thrown away via a silent conversion to Unit (it's a Scala wart... enabling -Ywarn-value-discard will show the warning).

To explicitly send the result of actorFoo() to the requestor, try something like:

override def receive: Receive = {
  case fetchData =>
    sender ! actorFoo()
}

Upvotes: 1

Related Questions