按需演员获取或创建 [英] on demand actor get or else create
问题描述
我可以用 actorOf
创建演员,并用 actorFor
查看他们.我现在想通过一些 id:String
获取一个演员,如果它不存在,我希望它被创建.像这样:
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
}
}
但这不起作用,因为 isTerminated
总是正确的,我得到 actor name 1 is not unique!
第二次调用的异常.我想我在这里使用了错误的模式.有人可以帮助如何实现这一目标吗?我需要
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
- 按需创建演员
- 按 id 查找演员,如果不存在则创建他们
- 继续破坏的能力,因为我不知道我是否会再次需要它
我应该为此使用调度程序还是路由器?
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 }
}
}
}
他的伴生对象
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]
}
...
}
推荐答案
我使用 akka 的时间并不长,但演员的创建者默认是他们的主管.因此,父母可以监听他们的终止;
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 }
这是一个解决方案吗?我必须说我没有完全理解你的意思 终止总是正确的 => 演员姓名 1 不是唯一的!"
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!"
这篇关于按需演员获取或创建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!