2013-04-27 71 views
3

这是对my previous question的后续处理:如何保证Actor的响应时间?

假设我有一个演员,它每秒处理X个请求。但是有时会发生突发事件,并且客户端每秒发送Y > X个请求。现在我必须保证客户端在给定的超时时间内收到一个响应(以太网成功超时状态)。

假设我使用Scala和Akka,你会建议如何实现它?

回答

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" 
    } 
} 

你可以看看这个例子,我指定ask超时2秒钟,我的演员在响应之前3秒钟睡觉。在这种情况下,我将永远得到Failure包装TimeoutException。现在,超时处理并非是Scala的Future类的原生特性,但幸运的是,Akka增加了对其ask操作的超时支持。在引擎盖下,当你执行ask时,Akka创建了两个Promises;一个可以由参与者回复消息完成,另一个由HashedWheelTimer类中的计时器任务完成。然后,Akka从这两个Promise实例中获取Futures,并将它们与Future.firstCompletedOf合并为一个,因此您从?调用中返回的Future可以通过收到消息的actor或来自超时的响应来完成,无论先发生什么。