sarah w
sarah w

Reputation: 3515

How to use the Akka ask pattern without blocking

Hi I have a actor which is responsible for fetching data from a database, turning it into a list and sending it back to the sender. I am using the ask pattern to receive response from my actor, because I don't want to use await.result because this approach will block the thread which is not good.

I wrote the following code to get the response from my actor (I just skipped the db code to keep it simple but logic remains same) :

class MyActor extends Actor{
   var list = new MutableList[Int]()
   list+=1
   list+=2
   list+=3
   list+=4

   def receive ={
     case "returnAlist"=>
       println("sending back list "+list +"of size "+list.size)
       sender ! list
     case message => 
       unhandled(message)
   }
}

object Test extends App{
  val system = ActorSystem("testing")
  val MyActor = system.actorOf(Props[MyActor], name = "InstitutionUserSuggestion")
  implicit val timeout = Timeout(15 seconds)
  var ResultList = new MutableList[Int]()
  val future:Future[MutableList[Int]] = ask(MyActor,"returnAlist").mapTo[MutableList[Int]] 
  future.onComplete { 
    case Success(result)=>
      println(" in sucees start")
      println("value of result "+ result.size)
      println("ResultList=result")
      ResultList = result
      println("value of ResultList "+ ResultList.size)
      println("in Success end")
    case Failure(e)=>
      println(" in failure")
      e.printStackTrace()
  }

  println("returned list size is " + ResultList.size + " and its contents" + ResultList)


}

Here is the output of the code above:

sending back list MutableList(1, 2, 3, 4)of size 4
returned list size is 0 and its contenstsMutableList()
in sucees start
value of result 4
 ResultList=result
value of ResultList 4
 in Success end

My problem is that the onComplete code is executed at the end I need to display contents of my list ResultList on the console but this line

println("returned list size is "+ResultList.size +" and its contensts" +ResultList)

which I write after the onComplete block I think it is executing before the onComplete block, so at the end nothing is in the list ResultList, so I am unable to print its items to the console.

Please help me, what should I do to receive a list of items from the actor without blocking and after that display it on the console.

Upvotes: 3

Views: 2709

Answers (1)

Peter Neyens
Peter Neyens

Reputation: 9820

You don't want to block, by waiting on the response of the actor, so you are using Future correctly. The code in the onComplete function is executed, when your actor responds with the list.

And since you don't want to block and handle it asynchronously, your last println statement is executed while your actor has not yet responded.

You can print the content of the list in the onComplete block:

object Test extends App{
  val system = ActorSystem("testing")
  val MyActor = system.actorOf(Props[MyActor], name = "InstitutionUserSuggestion")
  implicit val timeout = Timeout(15 seconds)

  val future: Future[List[Int]] = ask(MyActor,"returnAlist").mapTo[List[Int]] 
  future.onComplete { 
    case Success(result)=>
      println("returned list size is " + result.size +" and its contents" + result)
    case Failure(e)=>
      println("in failure")
      e.printStackTrace()
  }
}

As a side note, I used an immutable List which is more idiomatic Scala than using mutable collections, like MutableList.

Upvotes: 2

Related Questions