繁体   English   中英

Akka.NET演员和包装器(可能与Rx)

[英]Akka.NET actors and wrappers (potentially with Rx)

我开始玩Actor模型 ,尤其是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的ISubject演员导向实现(我已经做过BTW,这很容易,但我再也不确定我是否对所有我都给予足够的重视应该)。

我也读过一些关于Typed Actors的内容 ,但我不是Scala专家,所以也许我没有抓住代码示例中的所有细节,而且我不确定它们是否已经在Akka.NET中可用( doc page is一个404

这看起来不错。 您应该考虑的是,默认情况下,演员有“最多一次”的交付保证,因此,您应该考虑到与您的演员沟通时可能无法获得回复。 (网络故障,崩溃的远程节点等)

在本地系统中,消息不太可能丢失,但从理论上讲,如果某人做了过于狂野的事情,演员系统可能会崩溃,从而演员死亡。

因此,当使用Ask与演员进行通信时,最好是安全并提供超时并处理该异常而不是永久阻止/等待。

从最新的预发布位(1.0之前版本)开始支持Async / Await。 然而,这不是推荐的方法。 更好地坚持使用PipeTo并明确。

另一件可以获得iffy的事情是,因为在你的例子中你将actor视为Key Value商店,这很好。 而且你的消息也是不可变的,这也很好。 但是如果Key或Value属性是ref类型,并且人们可以从外部改变那些,例如IGetSet的消费者可能导致actor内部的RC问题,因为当另一个线程正在改变它们时,actor可能会读取这些值。

ActorSystems也非常昂贵,尽量避免使用多个系统,每个进程的目标是一个系统。

除此之外,你很高兴。

暂无
暂无

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

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