简体   繁体   English

有没有办法让Akka.NET中给定节点上的所有实例化actor都可用

[英]Is there a way to get all instantiated actors currently available on a given node in Akka.NET

I have the following code in my application which creates an instance of an Akka.NET actor in my cluster as such: 我在我的应用程序中有以下代码,它在我的集群中创建一个Akka.NET actor的实例:

_actorSystem = ActorSystem.Create("mycluster");
_actoraActor = this._actorSystem.ActorOf<ActorA>();

Note that I deliberately omit the name property as I intend to create N actors of type ActorA and don't want to manage the names. 请注意,我故意省略name属性,因为我打算创建类型为ActorA的N个actor,并且不想管理这些名称。 Running the above I end up with an actor which has an ID that looks like this: 运行上面我最后得到一个演员,其ID如下所示:

akka://mycluster/user/$a#1293118665

The problem I run into is trying to determine the Actor path from a different node. 我遇到的问题是尝试从不同的节点确定Actor路径。 So for example I have tried doing the following: 例如,我尝试过以下操作:

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;
    }
}

Where via leveraging of the cluster MEMBER-UP event I try to send an Identify request to the new member but the problem I run into is the ClusterEvent.MemberUp object provided does not contain information regarding the actors within the node but only appears to contain a node reference that looks like this: 在利用集群MEMBER-UP事件的情况下,我尝试向新成员发送一个Identify请求,但我遇到的问题是提供的ClusterEvent.MemberUp对象不包含有关节点内actor的信息,但似乎只包含一个节点引用如下所示:

akka.tcp://mycluster@localhost:666 akka.tcp:// myCluster中@本地:666

Which makes perfect sense because its the node that has come online, not an actor. 这是完全有道理的,因为它已经上线的节点,而不是演员。

If I change my code to use a named actor: 如果我更改我的代码以使用命名的actor:

_actorSystem = ActorSystem.Create("mycluster");
_actoraActor = this._actorSystem.ActorOf<ActorA>("actora");

I can then successfully query the service how I need. 然后,我可以成功查询服务我需要的方式。 This is what you would expect when you have a named actor but there appears to be no way to actually externally determine instances of running actors on a node. 这是您在拥有一个命名actor时所期望的,但似乎无法实际外部确定节点上正在运行的actor的实例。

So, when using N instances of unnamed actors what are the correct steps to identify references to the actors you are interested in, specifically when the actors have been generated without a name? 因此,当使用未命名演员的N个实例时,识别对您感兴趣的演员的引用的正确步骤是什么,特别是在没有名称的情况下生成演员时?

EDIT: 编辑:

I've decided to restate the question because I didn't adequately describe it initially. 我已经决定重申这个问题,因为我最初没有充分描述它。 The correct expression of this question is: 这个问题的正确表达是:

"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?" “当你所拥有的只是节点路径时,有没有办法让外部演员在给定节点上当前可用的所有实例化演员?”

To me it just seems like this should be something built into the base framework UNLESS there is some sort of design consideration that I don't fully understand. 对我来说,这似乎应该是基础框架内置的东西,除非有一些我不完全理解的设计考虑因素。

I also note that I think it's likely the correct approach to my particular problem might just be that I am trying to do a Pub/Sub and this https://getakka.net/articles/clustering/distributed-publish-subscribe.html is more appropriate. 我还注意到,我认为我的特定问题的正确方法可能就是我正在尝试做Pub / Sub这个https://getakka.net/articles/clustering/distributed-publish-subscribe.html是更合适。

I think for your purposes here you should consider leveraging the actor hierarchy. 我认为在这里您应该考虑利用actor层次结构。

Instead of creating a top-level actor with a randomly assigned name, create a parent with a hard-coded name: 不是创建具有随机分配名称的顶级actor,而是创建具有硬编码名称的父级:

_actorSystem = ActorSystem.Create("mycluster");
_delegatorParent = this._actorSystem.ActorOf<ParentActorA>("parent");

This parent actor can spawn any number of children, and it can spawn children in response to incoming messages: 这个父actor可以生成任意数量的子节点,它可以生成子节点以响应传入的消息:

_delegatorParent.Tell(new WorkItem("someWork", 1200));

This could cause the parent to create a child actor that actually executes the work: 这可能会导致父级创建实际执行工作的子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);
       });
    }
}

This gives you a fixed entry point into this node / family of actors while still having the ability to spin up new actors that don't have specific names. 这为您提供了一个固定的入口点到这个节点/演员系列,同时仍然能够启动没有特定名称的新演员。 Just look up the parent with the static name, not the children who execute the work. 只需使用静态名称查找父级,而不是执行工作的子级。

While you're at it you may also want to take a look at pool routers and the child per entity pattern in Akka.NET . 当你在它的时候,你可能还想看看Akka.NET中的池路由器和每个实体模式子节点

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM