Я могу создать актеров с 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!
исключение для второго вызова. Наверное, я использую неправильный шаблон здесь. Может кто-то помочь, как достичь этого? Мне нужно
- Создание актеров по требованию
- Lookup актеров по идентификатору, и если нет создавать их
- способность разрушать дальше, так как я не знаю, если мне нужно будет снова
Должен ли я использовать Диспетчер или Маршрутизатор для этого?
Решение Как было предложено, я использую конкретный Супервизор, который содержит доступных участников на карте. Можно попросить предоставить одного из его детей.
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]
}
...
}
Да, это решение. Я попытался не создавать собственный реестр (Карта) и использовать для этого Actor Path. Но в любом случае я планировал реализовать супервайзера, и, похоже, другого пути нет. Некоторые предпосылки: я использую Playframework и их предоставленный контекст – martin
Спасибо за этот ответ. Мне никогда не приходило в голову, что родительский актер увидит сообщение Terminated. Это имеет смысл, но меня повесили на том, что нужно «смотреть» на ребенка, чтобы справиться с завершенным (что делает намного меньше смысла) ... – jxstanford
Похоже на решение OK, но я не слишком люблю используя этот 'var' в любом месте рядом с параллельными вещами. - это 'mutable.Map' немного лучший вариант? – Ashesh