我正在使用Scala 2.10,Akka 2.1和Play 2.1。当我向后端发送http请求时,我ask
一个演员来计算某些东西。如果在超时之前返回计算结果,则返回计算结果,否则返回不同的字符串。请参阅下面的代码。
val futureInt: Future[Int] = ask(testActor, Calculate(number.toInt)).mapTo[Int]
val timeoutFuture = play.api.libs.concurrent.Promise.timeout("Oops", 2.seconds)
Async {
Future.firstCompletedOf(Seq(futureInt, timeoutFuture)).map {
case i: Int => Ok("Got result " + i)
case t: String => Ok("timeout expired")
}
}
演员如下:
class TestActor() extends Actor {
def receive = {
case Calculate(tonumber: Int) =>
for (a <- 1 to tonumber) {
val c: Double = scala.math.pow(a, 2)
println("a: " + a + ", c: " + c)
}
12345 // hardcoded value to return when the calculation finishes
case _ =>
println("bah")
}
}
我的问题是,即使演员在超时之前完成,Future也不会“返回”任何内容,因此超时总是会到期。我究竟做错了什么?非常感谢。
答案 0 :(得分:3)
来自http://doc.akka.io/docs/akka/snapshot/scala/actors.html
使用ask会向tell接收Actor发送消息,而接收actor必须回复发件人!回复以使用值完成返回的Future。
和
警告强>
要通过例外完成未来,您需要向发件人发送失败邮件。当actor在处理消息时抛出异常时,这不会自动完成。
所以不要像通常的scala函数那样“返回”,而是按照
的方式做一些事情def receive = {
case Calculate(tonumber: Int) =>
...
sender ! 12345
case _ =>
sender ! akka.actor.Status.Failure(new InvalidArgumentException)
}