Есть ли способ получить все экземпляры действующих экземпляров, доступные в данный момент на данном узле в Akka.NET? - PullRequest
0 голосов
/ 25 июня 2018

У меня есть следующий код в моем приложении, который создает экземпляр актера Akka.NET в моем кластере как таковой:

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

Обратите внимание, что я намеренно опускаю свойство name, так как намереваюсь создать Nактеры типа ActorA и не хотят управлять именами.Запустив вышеизложенное, я получаю актера с идентификатором, который выглядит следующим образом:

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

Проблема, с которой я сталкиваюсь, заключается в попытке определить путь актера из другого узла.Например, я попытался сделать следующее:

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 не содержит информации об актерах в узле, а только содержит ссылку на узел, которая выглядит следующим образом:

akka.tcp: // mycluster @ localhost: 666

Это имеет смысл, потому что это узел, который подключился к сети, а не актер.

Если я изменю свой код на использованиеименованный актер:

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

Затем я могу успешно запросить службу, как мне нужно.Это то, что вы ожидаете, когда у вас есть именованный актер, но, похоже, нет никакого способа фактически внешне определить экземпляры запущенных актеров на узле.

Итак, при использовании N экземпляров неназванных актеров, что является правильнымшаги для определения ссылок на актеров, которые вас интересуют, особенно когда актеры были созданы без имени?

РЕДАКТИРОВАТЬ:

Я решилчтобы переформулировать вопрос, потому что я не описал его изначально.Правильное выражение этого вопроса:

«Есть ли способ получить все экземпляры действующих экземпляров, доступные в данный момент на данном узле, от внешнего субъекта, когда у вас есть только путь к узлу?»

Мне просто кажется, что это должно быть что-то встроенное в базовую платформу, ЕСЛИ У меня есть некое понимание дизайна, которое я не до конца понимаю.

Я также отмечаю, чтоЯ думаю, что, скорее всего, правильный подход к моей конкретной проблеме может заключаться в том, что я пытаюсь создать Pub / Sub, и этот https://getakka.net/articles/clustering/distributed-publish-subscribe.html более уместен.

1 Ответ

0 голосов
/ 27 июня 2018

Я думаю, что для ваших целей вы должны рассмотреть использование иерархии акторов.

Вместо создания актера верхнего уровня со случайно назначенным именем, создайте родителя с жестко закодированным именем:

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

Этот родительский субъект может порождать любое количество дочерних элементов и порождать потомков в ответ на входящие сообщения:

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

Это может привести к тому, что родительский актер создаст дочерний субъект, который фактически выполняетработа:

public class ParentActorA{
    public ParentActorA(){
       Receive<WorkItem>(x => {
          // create new child to carry out the work
          var delegatorActor = Context.ActorOf<ActorA>();
          delegatorActor.Forward(x);
       });
    }
}

Это дает вам фиксированную точку входа в этот узел / семейство актеров, в то же время имея возможность раскручивать новых актеров, у которых нет конкретных имен.Просто посмотрите на родителя со статическим именем, а не на детей, которые выполняют работу.

Пока вы занимаетесь этим, вам также может понадобиться взглянуть на маршрутизаторы пула и шаблон child per entity в Akka.NET .

...