【发布时间】:2020-01-03 10:14:00
【问题描述】:
是否可以检查 ActorSystem 中是否存在演员?
我只是不想将 IActorRef 引用传递给每个演员的构造函数,并且希望有类似 GetOrCreate 方法来实例化所需的演员。所以它可能就像一个我会在整个 Actor 系统中使用的单例 Actor。
【问题讨论】:
是否可以检查 ActorSystem 中是否存在演员?
我只是不想将 IActorRef 引用传递给每个演员的构造函数,并且希望有类似 GetOrCreate 方法来实例化所需的演员。所以它可能就像一个我会在整个 Actor 系统中使用的单例 Actor。
【问题讨论】:
您可以使用ActorSelection 来检查是否存在任何参与者,以要求其识别自己:
var selection = Context.ActorSelection(actorPath);
/// if there's no actor, this operation can timeout
var reply = await selection.Ask<ActorIdentity>(new Identify(null), timeout);
虽然这在任何地方都有效,即使跨越网络边界,您也不能“仅仅”从任何地方创建一个演员。为了创建 Actor,需要一个父级 - 一个 Actor 系统或另一个 Actor。
获取或创建逻辑可以非常简单地从演员内部完成:
IActorRef GetOrCreate(string childName)
{
var child = Context.Child(childName);
if (Equals(child, ActorRefs.Nobody))
child = Context.ActorOf(Props.Create(() => new ChildActor()), childName);
return child;
}
如果你需要让它在分布式环境中工作,这个功能由Akka.Cluster.Sharding插件覆盖。
【讨论】:
IActorRef 并将其缓存在更接近必须使用它的实际位置的地方 - 拥有一个带有 key=>IActorRef 字典的演员是很常见的传播给整个系统的其他参与者。可以停止 Ofc 演员 - 在这种情况下 IActorRef 将无效。 watching 解决了这个问题:它适用于本地和远程参与者。
ActorSelection 有一个名为“ResolveOne”的方法,用于检查演员的存在。根据文档:
解析匹配此选择的 IActorRef。结果返回 作为一个使用 IActorRef 完成的任务,如果这样的参与者 存在。如果没有,则以失败 ActorNotFoundException 完成 演员存在或识别未在提供的范围内完成 超时
这个方法可以这样使用:
var actorRef = await Context.ActorSelection("Path of Actor !").ResolveOne(TimeSpan.FromSeconds(5));
【讨论】: