簡體   English   中英

有沒有辦法讓Akka.NET中給定節點上的所有實例化actor都可用

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM