如何在不阻塞的情况下使用Akka ask模式

时间:2015-06-23 11:09:19

标签: scala asynchronous akka future

您好我有一个演员,负责从数据库中获取数据,将其转换为列表并将其发送回发件人。我正在使用ask模式来接收我的演员的回复,因为我不想使用await.result,因为这种方法会阻止不好的线程。

我编写了以下代码来获取我的actor的响应(我刚刚跳过db代码以保持简单但逻辑保持不变):

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)


}

以下是上述代码的输出:

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

我的问题是onComplete代码在最后执行我需要在控制台上显示我的列表ResultList的内容但是这行

println("returned list size is "+ResultList.size +" and its contensts" +ResultList)
我在onComplete块之后写的

我认为它在onComplete块之前执行,所以最后列表ResultList中没有任何内容,所以我无法打印它项目到控制台。

请帮助我,我该怎么办才能从演员那里接收一个没有阻止的项目列表,然后在控制台上显示它。

1 个答案:

答案 0 :(得分:2)

您不想通过等待演员的响应来阻止,因此您正确使用Future。当你的actor用列表响应时,执行onComplete函数中的代码。

由于你不想异步地阻止和处理它,你的最后一个println语句会在你的演员尚未响应时执行。

您可以在onComplete块中打印列表内容:

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()
  }
}

作为旁注,我使用了一个不可变的List,这比使用可变集合更加惯用Scala,比如MutableList