【问题标题】:Finding a previously persisted Akka actor with an indirect reference使用间接引用查找先前持久化的 Akka actor
【发布时间】:2017-07-25 11:21:49
【问题描述】:

在我目前正在构建的系统中,有很多地方可以通过多种方式联系同一个演员。例如,如果您有固定的汽车演员,您可以使用 VIN 或车牌。

由于我们需要一个“真实姓名”来在重新创建演员时用作演员名称/持久性 ID,这些“查找/引用”本身就是演员,以他们的键命名,只保留他们引用的演员的 ID .

这似乎是正确的方法吗?似乎很多演员并不是真正的演员,只是代理。

【问题讨论】:

    标签: akka akka.net akka-persistence


    【解决方案1】:

    已编辑以更新答案。

    听起来我们有一个包含汽车集合的存储库,每辆汽车都可以有一个 VIN 或 REG 号(或序列号或底盘号......唯一标识汽车的东西)。

    ID    |  VIN  |  REG
    car1  |  ABC  |  123
    car2  |  DEF  |  456
    

    我们还有一个持久化的CarActor,它封装了汽车的状态和逻辑。

    public class CarActor : PersistentReceiveActor
    {
        string _id;
        public override string PersistenceId { get { return _id; } }
    
        public CarActor(string id)
        {
            _id = id;
        }
    
        public static Props Props(string id)
        {
            return Akka.Actor.Props.Create(() => new CarActor(id));
        }     
    }
    

    因为我们需要一个“真实姓名”来用作演员姓名/持久性 重新创建演员时的 ID,这些“查找/引用”本身就是 演员,以其密钥命名,仅保留演员的 ID 他们参考。

    这似乎是正确的方法吗?好像很多 演员不是真正的演员,只是代理。

    为了简单起见,我们可以定义一个消息来封装可以识别汽车的各种 ID 号。然后可以将此消息传递给我们的 Actor 系统进行处理。

    public class CarCommand
    {
        public string Vin { get; private set; }
        public string Reg { get; private set; }
    }
    

    Best practice 是有一个主管或路由器参与者,负责实体域并选择将每个实体表示为其自己的参与者。这个主管可以接收CarCommand 消息,通过 VIN 或 REG 查找汽车的 ID,并找到/创建一个子 Actor 来处理该消息。

    public class CarSupervisor : ReceiveActor
    {
        //in reality this would be a repository e.g. a DB context... it would
        //be even better if this was handled in another Actor that this Actor
        //has access to
        readonly IEnumerable<Cars> _cars;
    
        public CarSupervisor(IEnumerable<Cars> cars)
        {
            _cars = cars;
            Receive<CarCommand>(command => 
            {
                //find a car by VIN or REG or other variable
                var car = _cars.First(c => c.VIN == command.VIN);
                //see if any child actors have been created for this car instance
                var child = Context.Child(car.Id);
                //if we don't have an incarnation yet, create one
                if (Equals(child, ActorRefs.Nobody))
                    child = Context.ActorOf(CarActor.Props(car.Id), car.Id));
                //tell the child to process the message
                child.Forward(command);
            });
        }      
    }
    

    【讨论】:

    • 感谢您的回答,但我不确定您是否理解了这个问题。这个演员没有天生的关键;我可能试图通过 VIN、车牌等找到它。除了为每个参考(VIN,车牌)指定一个单独的演员之外,还有其他方法可以通过这些方法找到汽车吗?此外,内存列表也不可行。
    • VIN 或 Reg 不是唯一的密钥吗?例如。一个 VIN 只能与一辆汽车相关,该汽车在我们的存储库中有一个 ID。 IdSupplierActor 可以接收包含 VIN 或 Reg 等的消息,并返回相关汽车的 ID。或者CarFinderActor 接收消息并返回Actor 的路径。
    • 这就是我的意思;这将如何使用 Akka Persistence 实现?让演员在上面写上每个 VIN 或车牌号是不可行的。谢谢。
    • @james - 在我们讨论后编辑答案...希望这会有所帮助:)
    • @ChimaOsuji 我是否正确理解您将使用传统数据库来获取(或存储)对单个 ID 的标识引用以用作演员的姓名?将数据库与演员系统相结合?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-29
    • 1970-01-01
    • 2012-04-24
    • 1970-01-01
    • 2016-02-06
    • 2016-03-07
    • 1970-01-01
    相关资源
    最近更新 更多