我正在使用 Scala 2.10、Akka 2.1 和 Play 2.1。当我向我的后端发送一个 http 请求时,我要求
一个参与者计算一些东西。这个想法是如果它在超时之前返回,则返回计算结果,否则返回一个不同的字符串。请参阅下面的代码。
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")
}
}
Actor 如下:
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")
}
}
我的问题是,即使 actor 在超时之前完成,Future 也不会“返回”任何内容,因此超时总是会过期。我究竟做错了什么?非常感谢。
最佳答案
来自 http://doc.akka.io/docs/akka/snapshot/scala/actors.html
Using ask will send a message to the receiving Actor as with tell, and the receiving actor must reply with sender ! reply in order to complete the returned Future with a value.
和
Warning
To complete the future with an exception you need send a Failure message to the sender. This is not done automatically when an actor throws an exception while processing a message.
因此,不要像在通常的 Scala 函数中那样“返回”,而是按照以下方式做一些事情
def receive = {
case Calculate(tonumber: Int) =>
...
sender ! 12345
case _ =>
sender ! akka.actor.Status.Failure(new InvalidArgumentException)
}
关于Scala Akka Play, future 不会回来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14772963/