这是my previous question的后续行动:
假设我有一个actor,每秒处理X
个请求。但有时会有突发,客户端每秒发送Y > X
个请求。现在我必须保证客户端在给定的超时时间内收到响应(ether 成功或超时状态)。
假设我使用Scala和Akka你会建议实现它吗?
答案 0 :(得分:3)
首先,一个显示超时处理的小代码示例:
import akka.actor._
import akka.util.Timeout
import scala.concurrent.duration._
import akka.pattern._
import scala.util._
import java.util.concurrent.TimeoutException
object TimeoutTest {
def main(args: Array[String]) {
val sys = ActorSystem("test-system")
implicit val timeout = Timeout(2 seconds)
implicit val ec = sys.dispatcher
val ref = sys.actorOf(Props[MyTestActor])
val fut = ref ? "foo"
fut onComplete{
case Success(value) => println("Got success")
case Failure(ex:TimeoutException) => println("Timed out")
case Failure(ex) => println("Got other exception: " + ex.getMessage)
}
}
}
class MyTestActor extends Actor{
def receive = {
case _ =>
Thread.sleep(3000)
sender ! "bar"
}
}
你可以在这个例子中看到,我指定{2}的ask
超时,我的演员在响应前3秒睡觉。在这种情况下,我将始终获得Failure
包裹TimeoutException
。现在,超时处理不是Scala的Future
类本机,但幸运的是,Akka为其ask
操作添加了超时支持。在幕后,当您执行ask
时,Akka会创建两个Promises
;一个可以由响应消息的actor完成,另一个由HashedWheelTimer
类中的计时器任务完成。然后,Akka从这两个Futures
个实例中获取Promise
并将其与Future.firstCompletedOf
组合成一个,以便从Future
调用中返回的?
可以是无论先发生什么事情,都可以通过接收消息的演员的响应或超时完成。
答案 1 :(得分:1)
这取决于你如何使用演员。如果你正在使用'问' (如actor ? msg
),您将收到一个在指定时间后超时的未来。
请参阅http://doc.akka.io/docs/akka/snapshot/scala/futures.html(与演员合作)
您可以在未来添加onFailure挂钩,以便在将来超时时向客户端发送错误响应。
未来api:http://www.scala-lang.org/api/current/index.html#scala.concurrent.Future