使用间接引用查找以前保留的Akka参与者

使用间接引用查找以前保留的Akka参与者,akka,akka.net,akka-persistence,Akka,Akka.net,Akka Persistence,在我目前正在构建的系统中,有很多地方可以通过多种方式联系到同一个参与者。例如,如果你有一个持久的汽车演员,你可以使用VIN或车牌 由于在重新创建参与者时需要一个“真实名称”用作参与者名称/持久性ID,因此这些“查找/引用”本身就是参与者,以其键命名,仅持久化它们引用的参与者的ID 这似乎是正确的方法吗?似乎有很多演员不是真正的演员,只是代理。编辑以更新答案 听起来好像我们有一个存储库,其中包含一组汽车,每辆汽车都可以有一个VIN或注册号(或序列号,或底盘号…唯一标识汽车的东西) 我们还有一个持久

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

由于在重新创建参与者时需要一个“真实名称”用作参与者名称/持久性ID,因此这些“查找/引用”本身就是参与者,以其键命名,仅持久化它们引用的参与者的ID


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

编辑以更新答案

听起来好像我们有一个存储库,其中包含一组汽车,每辆汽车都可以有一个VIN或注册号(或序列号,或底盘号…唯一标识汽车的东西)

我们还有一个持久的
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重新创建参与者时,这些“查找/引用”本身就是 actor,以其键命名,只保留actor的ID 它们是参考文献

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

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

public class CarCommand
{
    public string Vin { get; private set; }
    public string Reg { get; private set; }
}
是有一个主管或路由器参与者负责一个实体域,并选择将每个实体表示为自己的参与者。该主管可以接收
CarCommand
消息,通过VIN或REG查找车辆ID,并查找/创建子参与者以处理该消息

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);
        });
    }      
}
公共类车辆主管:接受者
{
//实际上,这将是一个存储库,例如数据库上下文……它将
//如果这是在另一个演员身上处理的话会更好
//有权访问
只读IEnumerable\u汽车;
公共车辆主管(IEnumerable cars)
{
_汽车=汽车;
接收(命令=>
{
//通过VIN或REG或其他变量查找汽车
var car=_cars.First(c=>c.VIN==command.VIN);
//查看是否为此汽车实例创建了任何子角色
var child=Context.child(car.Id);
//如果我们还没有化身,就创造一个
if(等于(儿童、演员、无人))
child=Context.ActorOf(CarActor.Props(car.Id),car.Id));
//告诉孩子处理消息
儿童前进(命令);
});
}      
}

谢谢你的回答,但我不确定你是否理解这个问题。这个演员没有天生的钥匙;我可以试着通过VIN、车牌号等来找到它。除了每个参考资料(VIN、车牌号)都有一个单独的参与者外,还有没有其他方法可以通过其中任何一个来找到汽车?此外,内存中的列表也不可行。VIN或Reg不是唯一的密钥吗?例如,一个VIN只能与一辆在我们的存储库中具有ID的汽车相关。
IdSupplierActor
可以接收包含VIN或Reg等信息,并返回有问题车辆的ID。或者,
CarFinderActor
获取消息并返回到
Actor
的路径;如何使用Akka持久性实现这一点?让一个演员把每一个VIN或车牌号码都写在上面是不可行的。谢谢。@james-我们讨论后编辑的答案。。。希望这有帮助:)@ChimaOsuji我是否正确地理解您会使用常规数据库获取(或存储)单个ID的标识引用,以用作演员的名字?将DB与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);
        });
    }      
}