Akka.NET актеры и оболочки (возможно, с Rx)

Я начал играть с моделью актера, в частности с Akka.NET. В целом, я думаю, что у меня есть хорошее представление о том, что это такое, но, конечно, дьявол кроется в деталях. Я думал о принятии Akka.NET в уже существующую кодовую базу, и поэтому я хотел бы оценить, сколько из существующих абстракций можно сохранить. Идея состоит в том, что некоторые конкретные высокоуровневые интерфейсы могут быть сохранены, и некоторые реализации адаптера будут написаны так, чтобы беспрепятственно перемещаться назад и вперед по всему миру участников и пользователей существующих интерфейсов, но я не уверен, рекомендуется ли это и что типы конкретных проблем, с которыми мне следует столкнуться.

Тривиальный пример:

public interface IGetSet<in TK, TV>
{
    TV Get(TK key);
    void Set(TK key, TV value);
}

public class GetSet<TK, TV> : IGetSet<TK, TV>
{
    private readonly ActorRef _getSetActor;

    public GetSet(ActorRefFactory system)
    {
        _getSetActor = system.ActorOf(Props.Create(() => new GetSetActor()));
    }

    public TV Get(TK key)
    {
        var x =  _getSetActor.Ask<TV>(new GetSetActor.Get(key));
        return x.Result;  //blocking, I know, it's just an example
    }

    public void Set(TK key, TV value)
    {
        _getSetActor.Tell(new GetSetActor.Set(key, value));
    }

    class GetSetActor : ReceiveActor
    {
        readonly Dictionary<TK, TV> _values = new Dictionary<TK, TV>();

        public class Get
        {
            public Get(TK key) { Key = key; }
            public TK Key { get; private set; }
        }

        public class Set
        {
            public Set(TK key, TV value) { Key = key; Value = value; }
            public TK Key { get; private set; }
            public TV Value { get; private set; }
        }

        public GetSetActor()
        {
            Receive<Get>(g => Sender.Tell(_values[g.Key], Self));
            Receive<Set>(g => _values[g.Key] = g.Value);
        }
    }
}

...

var gs = new GetSet<string, int>(ActorSystem.Create("Wasp"));
gs.Set("a", 42);
var i = gs.Get("a");

В этом случае IGetSet Интерфейс происходит из традиционного мира, и его реализация позволяет нам переходить от мира к актеру. Я старался быть вежливым с актерами, которые никогда не использовались способами, отличными от передачи сообщений, поэтому в целом это (тривиальное, конечно) упражнение выглядит многообещающе, но я хотел бы знать, стоит ли уделять внимание чему-то еще с того дня 1.

Я читал о том, как избежать дополнительного асинхронного кода, не основанного на актерах, который замыкает состояние актеров, это ясно, и я этого не делаю, но, возможно, есть еще кое-что, чего я не вижу. Моя конечная цель - использовать этот шаблон достаточно широко, вплоть до того, что я бы написал актер-ориентированные реализации Rx's. ISubject (что, кстати, я уже сделал, и это было легко, но опять же я не уверен, что уделил достаточно внимания всем, что я должен).

Я также немного читал о Typed Actors, но я не эксперт по Scala, поэтому, возможно, я не понимаю все детали из примеров кода, и я не уверен, что они уже доступны в Akka.NET ( страница документа 404)

1 ответ

Решение

Это выглядит хорошо. Следует учитывать, что по умолчанию актеры имеют гарантию доставки "максимум один раз", поэтому следует учитывать, что при общении с актером ответ может не получиться. (Сбой сети, поломка удаленных узлов и т. Д.)

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

Поэтому при общении с актером с помощью Ask лучше быть в безопасности и предоставить тайм-аут и обработать это исключение вместо блокировки / ожидания навсегда.

Async / Await поддерживается начиная с последних битов перед выпуском (до 1.0). Однако это не рекомендуемый подход. лучше придерживаться PipeTo и быть явным.

Еще одна вещь, которая может показаться сомнительной, заключается в том, что в вашем примере вы рассматриваете актера как хранилище Key Value, что вполне нормально. И ваши сообщения также неизменны, что тоже хорошо. Но если свойства Key или Value являются ссылочными типами, и люди могут изменять их извне, например, потребители IGetSet это может вызвать проблемы с RC внутри субъекта, поскольку субъект может прочитать эти значения, когда другой поток изменяет их..

ActorSystems также довольно дорогие, старайтесь не раскручивать много систем, стремитесь к одной системе на процесс.

Кроме этого, вы готовы идти.

Другие вопросы по тегам