有没有办法让 Akka.NET 中的给定节点上当前可用的所有实例化角色
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>();
请注意,我故意省略了名称 属性,因为我打算创建 N 个类型为 ActorA 的演员并且不想管理这些名称。 运行 以上我最终得到一个 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
对象provided 不包含有关节点内参与者的信息,但似乎仅包含如下所示的节点引用:
akka.tcp://mycluster@localhost:666
这很有道理,因为它是上线的节点,而不是演员。
如果我更改我的代码以使用指定的参与者:
_actorSystem = ActorSystem.Create("mycluster");
_actoraActor = this._actorSystem.ActorOf<ActorA>("actora");
然后我可以成功查询我需要的服务。当你有一个命名的演员时,这就是你所期望的,但似乎没有办法从外部实际确定节点上 运行 宁演员的实例。
那么,当使用未命名演员的 N 个实例时,识别对您感兴趣的演员的引用的正确步骤是什么,特别是当演员是在没有名字的情况下生成的?
编辑:
我决定重述这个问题,因为我最初没有充分描述它。这道题的正确表达是:
"Is there a way to get all instantiated actors currently available on
a given node from a external actor when all you have is the node path?"
对我来说,这似乎应该内置到基本框架中,除非有某种我不完全理解的设计考虑。
我还注意到,我认为解决我的特定问题的正确方法可能只是我正在尝试做一个 Pub/Sub,而这个 https://getakka.net/articles/clustering/distributed-publish-subscribe.html 更合适。
我认为出于您的目的,您应该考虑利用参与者层次结构。
与其创建具有随机分配名称的顶级 actor,不如创建具有硬编码名称的父级:
_actorSystem = ActorSystem.Create("mycluster");
_delegatorParent = this._actorSystem.ActorOf<ParentActorA>("parent");
这个父 actor 可以生成任意数量的子 actor,它可以生成子 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);
});
}
}
这为您提供了进入此节点/actor 系列的固定入口点,同时仍然能够启动没有特定名称的新 actor。只需查找具有静态名称的父项,而不是执行工作的子项。
在学习的同时,您可能还想看看池路由器和 child per entity pattern in Akka.NET。
我的应用程序中有以下代码,它在我的集群中创建了一个 Akka.NET actor 的实例:
_actorSystem = ActorSystem.Create("mycluster");
_actoraActor = this._actorSystem.ActorOf<ActorA>();
请注意,我故意省略了名称 属性,因为我打算创建 N 个类型为 ActorA 的演员并且不想管理这些名称。 运行 以上我最终得到一个 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
对象provided 不包含有关节点内参与者的信息,但似乎仅包含如下所示的节点引用:
akka.tcp://mycluster@localhost:666
这很有道理,因为它是上线的节点,而不是演员。
如果我更改我的代码以使用指定的参与者:
_actorSystem = ActorSystem.Create("mycluster");
_actoraActor = this._actorSystem.ActorOf<ActorA>("actora");
然后我可以成功查询我需要的服务。当你有一个命名的演员时,这就是你所期望的,但似乎没有办法从外部实际确定节点上 运行 宁演员的实例。
那么,当使用未命名演员的 N 个实例时,识别对您感兴趣的演员的引用的正确步骤是什么,特别是当演员是在没有名字的情况下生成的?
编辑:
我决定重述这个问题,因为我最初没有充分描述它。这道题的正确表达是:
"Is there a way to get all instantiated actors currently available on a given node from a external actor when all you have is the node path?"
对我来说,这似乎应该内置到基本框架中,除非有某种我不完全理解的设计考虑。
我还注意到,我认为解决我的特定问题的正确方法可能只是我正在尝试做一个 Pub/Sub,而这个 https://getakka.net/articles/clustering/distributed-publish-subscribe.html 更合适。
我认为出于您的目的,您应该考虑利用参与者层次结构。
与其创建具有随机分配名称的顶级 actor,不如创建具有硬编码名称的父级:
_actorSystem = ActorSystem.Create("mycluster");
_delegatorParent = this._actorSystem.ActorOf<ParentActorA>("parent");
这个父 actor 可以生成任意数量的子 actor,它可以生成子 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);
});
}
}
这为您提供了进入此节点/actor 系列的固定入口点,同时仍然能够启动没有特定名称的新 actor。只需查找具有静态名称的父项,而不是执行工作的子项。
在学习的同时,您可能还想看看池路由器和 child per entity pattern in Akka.NET。