[英]Is there a way to get all instantiated actors currently available on a given node in Akka.NET
我在我的应用程序中有以下代码,它在我的集群中创建一个Akka.NET actor的实例:
_actorSystem = ActorSystem.Create("mycluster");
_actoraActor = this._actorSystem.ActorOf<ActorA>();
请注意,我故意省略name属性,因为我打算创建类型为ActorA的N个actor,并且不想管理这些名称。 运行上面我最后得到一个演员,其ID如下所示:
akka://mycluster/user/$a#1293118665
我遇到的问题是尝试从不同的节点确定Actor路径。 例如,我尝试过以下操作:
public class ActorB : ReceiveActor
{
private readonly Cluster Cluster = Akka.Cluster.Cluster.Get(Context.System);
public ActorB()
{
this.Receive<ActorIdentity>(this.IdentifyMessageReceived);
this.ReceiveAsync<ClusterEvent.MemberUp>(this.MemberUpReceived);
}
protected override void PreStart()
{
this.Cluster.Subscribe(this.Self, ClusterEvent.InitialStateAsEvents, new[]
{
typeof(ClusterEvent.IMemberEvent),
typeof(ClusterEvent.UnreachableMember)
});
}
protected override void PostStop()
{
this.Cluster.Unsubscribe(this.Self);
}
private async Task<bool> MemberUpReceived(ClusterEvent.MemberUp obj)
{
if (obj.Member.HasRole("actora"))
{
//!The problem is here.
//ALL YOU ARE PROVIDED IS THE NODE ADDRESS:
//Obviously this makes sense because it's the node that has come alive
//and not the instances themselves.
string address = obj.Member.Address.ToString();
//akka.tcp://mycluster@localhost:666
Context.ActorSelection(address).Tell(new Identify(1));
}
return true;
}
private bool IdentifyMessageReceived(ActorIdentity obj)
{
return true;
}
}
在利用集群MEMBER-UP
事件的情况下,我尝试向新成员发送一个Identify
请求,但我遇到的问题是提供的ClusterEvent.MemberUp
对象不包含有关节点内actor的信息,但似乎只包含一个节点引用如下所示:
akka.tcp:// myCluster中@本地:666
这是完全有道理的,因为它已经上线的节点,而不是演员。
如果我更改我的代码以使用命名的actor:
_actorSystem = ActorSystem.Create("mycluster");
_actoraActor = this._actorSystem.ActorOf<ActorA>("actora");
然后,我可以成功查询服务我需要的方式。 这是您在拥有一个命名actor时所期望的,但似乎无法实际外部确定节点上正在运行的actor的实例。
因此,当使用未命名演员的N个实例时,识别对您感兴趣的演员的引用的正确步骤是什么,特别是在没有名称的情况下生成演员时?
编辑:
我已经决定重申这个问题,因为我最初没有充分描述它。 这个问题的正确表达是:
“当你所拥有的只是节点路径时,有没有办法让外部演员在给定节点上当前可用的所有实例化演员?”
对我来说,这似乎应该是基础框架内置的东西,除非有一些我不完全理解的设计考虑因素。
我还注意到,我认为我的特定问题的正确方法可能就是我正在尝试做Pub / Sub这个https://getakka.net/articles/clustering/distributed-publish-subscribe.html是更合适。
我认为在这里您应该考虑利用actor层次结构。
不是创建具有随机分配名称的顶级actor,而是创建具有硬编码名称的父级:
_actorSystem = ActorSystem.Create("mycluster");
_delegatorParent = this._actorSystem.ActorOf<ParentActorA>("parent");
这个父actor可以生成任意数量的子节点,它可以生成子节点以响应传入的消息:
_delegatorParent.Tell(new WorkItem("someWork", 1200));
这可能会导致父级创建实际执行工作的子actor:
public class ParentActorA{
public ParentActorA(){
Receive<WorkItem>(x => {
// create new child to carry out the work
var delegatorActor = Context.ActorOf<ActorA>();
delegatorActor.Forward(x);
});
}
}
这为您提供了一个固定的入口点到这个节点/演员系列,同时仍然能够启动没有特定名称的新演员。 只需使用静态名称查找父级,而不是执行工作的子级。
当你在它的时候,你可能还想看看Akka.NET中的池路由器和每个实体模式的子节点 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.