0

最近两天我一直在学习 Actor,我想创建一个过期缓存。现在我们使用租户模型,所以我希望每个租户都由一个参与者表示。我希望在需要时创建这些参与者,并在空闲一段时间后超时。

为了解决这个问题,我模拟了以下内容,因为我不知道提供的解决方案,并且正在寻找对该方法的任何批评或验证。

//A simple Message carrying just the name of the actor
case class Message(name:String)  

//Actor that will expire after a timeout period and stop itself
class ExpireActor extends Actor {

  val id = Random.nextInt(1000)
  context.setReceiveTimeout(100 milliseconds)
  def receive ={
    case Message(_) => println("Message: " + id + "   " + System.currentTimeMillis())
    case ReceiveTimeout => {
      println("Timeout: " + id + "   " + System.currentTimeMillis())
      self ! PoisonPill
    }
  }
}

//Router for creating actors on demand
case class LazyRouter() extends RouterConfig {

  def routerDispatcher: String = Dispatchers.DefaultDispatcherId
  def supervisorStrategy: SupervisorStrategy = SupervisorStrategy.defaultStrategy

  def createRoute(routeeProvider: RouteeProvider): Route = {
    {
      case (sender, Message(name)) ⇒
        routeeProvider.context
          .child(name)
          .map(a => List(Destination(sender, a)))
          .getOrElse{
            synchronized { 
              routeeProvider.context
                .child(name) //Dont want to call sync until I have to, so need to check existence again
                .map(a => List(Destination(sender, a)))
                .getOrElse{
                  val ref = routeeProvider.context.actorOf(Props[ExpireActor], name)
                  routeeProvider.registerRoutees(List(ref))
                  List(Destination(sender, ref))
                }
            }
          }
    }
  }
}
4

1 回答 1

1

我不确定我是否完全同意你的方法。演员很轻。当他们不做任何事情时,他们不会在 CPU 方面花费任何成本。为什么不事先预先创建所有缓存参与者(为每个可能的租户),这样路由器就不必担心synchronized它是否需要创建路由。然后,如果你想释放内存,而不是在演员空闲特定时间时停止他们,只需清除他们的内部状态(我假设是缓存的数据)。这将大大简化您的代码并使其更可靠(并且可能更快地启动)。

于 2013-08-14T15:44:15.560 回答