我可以創建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還是路由器?
解決方案 正如我所建議的,我使用了一個具體的監督者來保存地圖中的可用角色。可以要求提供他的一個孩子。
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]
}
...
}
是的,這是一個解決方案。我試圖避免創建我自己的註冊表(地圖),並使用演員路徑爲此。但我計劃無論如何實施一位主管,似乎沒有其他辦法。 一些背景:我正在使用Playframework及其提供的上下文 – martin
感謝您的回答。我從來沒有想到父母會看到Terminated消息。這是完全有道理的,但我被掛在不得不對孩子進行「監視」以處理終止(這使得很少有意義)... – jxstanford
看起來像一個好的解決方案,但我不太喜歡在接近併發的地方使用'var'。 是'mutable.Map'稍微好一點的選項? – Ashesh