Puedo crear actores con actorOf
y mirarlos con actorFor
. Ahora quiero obtener un actor por unos id:String
y si no existe, quiero que se cree. Algo como esto:a petición actor obtener o bien crear
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
}
}
Pero esto no funciona como isTerminated
es siempre verdad y me da actor name 1 is not unique!
excepción para la segunda llamada. Supongo que estoy usando el patrón incorrecto aquí. ¿Alguien puede ayudarme a lograr esto? Necesito
- Crear actores en la demanda
- actores en Buscar por ID y si no presentarlos crear
- capacidad de destruir el, ya que no sé si voy a volver a necesitar
¿Debo usar un Dispatcher o enrutador para esto?
Solución Como propuse, utilizo un Supervisor concreto que mantiene a los actores disponibles en un mapa. Se le puede pedir que proporcione uno de sus hijos.
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 }
}
}
}
Su objeto acompañante
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]
}
...
}
Sí, esta es una solución. Traté de evitar crear mi propio Registro (Mapa) y usar Actor Path para esto. Pero planeé implementar un supervisor de todos modos y parece que no hay otra manera. Algunos antecedentes: Estoy usando Playframework y su contexto proporcionado – martin
Gracias por esta respuesta. Nunca se me ocurrió que el actor principal vería el mensaje Terminado. Tiene todo el sentido, pero me quedé colgado al tener que "vigilar" al niño para manejar el terminado (lo cual tiene mucho menos sentido) ... – jxstanford
Parece una solución correcta, pero no me gusta demasiado usando esa 'var' en cualquier lugar cerca de cosas concurrentes. es 'mutable.Map' una opción marginalmente mejor? – Ashesh