我们怎样才能从各个演员那里得到结果,然后将所有演员的结果发送到play 2.2.0中的一个响应?

时间:2013-10-12 06:53:09

标签: scala akka play2-mini

case object getValues
case class Data(a: Any, b:Any)

class Testing extends Actor {
def receive = {
case "do something" => {
  val result2 = { User.getList }
  sender ! result2
}
case _ => println("done")
}
}

class Testing2 extends Actor {
def receive = {
case getValues =>
  val result2 = { User.getMap }
   }yield Data(a,b)
  val child = context.actorOf(Props[Testing], "child")//creating actor
  implicit val askTimeout = Timeout(1.second)//giving timeout
  val r = child ? "do something"
  val res = for {
    a <- r
  } yield (a)
  res map (p=>sender ! Data(p, result2))//sending response to the sender
}
}

//Controller
object Application extends Controller {

def testingActor2 = Action.async {
val system = ActorSystem("ActorSystem")
val actor1 = system.actorOf(Props[Testing2], "Testing2")
implicit val askTimeout = Timeout(1.second)
val res = actor1 ? getValues
implicit val formats = DefaultFormats
val result = for {
  r1 <- res
} yield r1
result map (r => { println(r); Ok("got result") })
}

我无法将两个演员的结果都归结为控制器。请告诉我如何使用演员,如果我必须得到他们的结果然后发送响应页面。

2 个答案:

答案 0 :(得分:3)

val f1 = Future(1) //ask first actor
  val f2 = Future(2) //ask second actor

  Future.sequence(List(f1, f2)).map(list => {
    //we got List[Int] here
    list
  })

答案 1 :(得分:2)

我可以在您的代码中看到的一个问题,可能不是整个问题,在Testing2中,您正在关闭sender,这是可变的并且可能导致问题。原因是,当map上运行异步Future时,sender可能已更改为其他ActorRef或可能无效(已切换为死亡)字母演员参考)无论哪种方式,你都不会得到回复到你打算去的地方。您只需执行以下操作即可解决此问题:

...
val res = for {
  a <- r
} yield (a)
val originator = sender
res foreach (p=>originator ! Data(p, result2))//sending response to the sender

或者您可以导入pipeTo模式,并按照以下方式执行:

import akka.pattern.pipeTo
...
val res = for {
  a <- r
} yield (a)
res map (p=> Data(p, result2)) pipeTo sender