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
также довольно дорогие, старайтесь не раскручивать много систем, стремитесь к одной системе на процесс.
Кроме этого, вы готовы идти.