on demand actor get or else create
akka, scala
Solution
I've not been using akka for that long, but the creator of the actors is by default their supervisor. Hence the parent can listen for their termination;
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
c
}
But obviously you need to watch for their Termination;
def receive = {
case Terminated(ref) => as = as filterNot { case (_, v) => v == ref }
Is that a solution? I must say I didn't completely understand what you meant by "terminated is always true => actor name 1 is not unique!"
Problem
I can create actors with `actorOf` and look them with `actorFor`. I now want to get an actor by some `id:String` and if it doesnt exist, I want it to be created. Something like this: ``` 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 } } ``` But this doesn't work as `isTerminated` is always true and I get `actor name 1 is not unique!` exception for the second call. I guess I am using the wrong pattern here. Can someone help how to achieve this? I need - Create actors on demand - Lookup actors by id and if not present create them - Ability to destroy on, as I don't know if I will need it again Should I use a Dispatcher or Router for this? Solution As proposed I use a concrete Supervisor that holds the available actors in a map. It can be asked to provide one of his children. ``` 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 } } } } ``` His companion object ``` 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] } ... } ```