Reputation: 3515
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
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