我可以使用actorOf
创建演员,并使用actorFor
查找它们。现在,我想通过一些id:String
获取一个演员,如果它不存在,则希望创建它。像这样:
def getRCActor(id: String):ActorRef = {
Logger.info("getting actor %s".format(id))
var a = system.actorFor(id)
if(a.isTerminated){
Logger.info("actor is terminated, creating new one")
return system.actorOf(Props[RC], id:String)
}else{
return a
}
}
但是这并不起作用,因为isTerminated
总是为真,我会得到第二次调用时的actor name 1 is not unique!
异常。我猜我在这里使用了错误的模式。有人能帮忙解决如何实现吗?我需要:
- 按需创建演员
- 按ID查找演员,如果不存在则创建演员
- 能够销毁演员,因为我不知道是否还需要它们
我应该使用Dispatcher还是Router来实现呢?
解决方案 正如所建议的那样,我使用具体的Supervisor来保存可用的演员映射。可以要求它提供其中一个子级。
class RCSupervisor extends Actor {
implicit val timeout = Timeout(1 second)
var as = Map.empty[String, ActorRef]
def getRCActor(id: String) = as get id getOrElse {
val c = context actorOf Props[RC]
as += id -> c
context watch c
Logger.info("created actor")
c
}
def receive = {
case Find(id) => {
sender ! getRCActor(id)
}
case Terminated(ref) => {
Logger.info("actor terminated")
as = as filterNot { case (_, v) => v == ref }
}
}
}
他的伴生对象
object RCSupervisor {
// this is specific to Playframework (Play's default actor system)
var supervisor = Akka.system.actorOf(Props[RCSupervisor])
implicit val timeout = Timeout(1 second)
def findA(id: String): ActorRef = {
val f = (supervisor ? Find(id))
Await.result(f, timeout.duration).asInstanceOf[ActorRef]
}
...
}
var
。mutable.Map
是一个稍微好一点的选择吗? - Ashesh