我正在使用Akka.net并希望从我在此处看到的http://qnalist.com/questions/5585484/ddd-eventsourcing-with-akka-persistence和https://gitter.im/petabridge/akka-bootcamp/archives/2015/06/25
中实现反应性等效的DDD存储库#39;我理解有一个协调器可以根据一些实时内存计数或一些经过的时间将大量参与者留在内存中的想法。
作为摘要(基于上面的链接)我试图:
如何拦截正在尝试发送给孩子的消息(步骤4),而是将他们路由到父母?或者换句话说,我希望孩子在发送Passivate消息的时候说出来,然后说'#34; hey不要再发送给我了消息,而是发送给我的父母而不是"。
这样可以节省我通过协调员路由所有内容(或者我是以错误的方式处理它而消息拦截无法做到,而应该通过父代理代理所有内容)?
我有我的留言合同:
public class GetActor
{
public readonly string Identity;
public GetActor(string identity)
{
Identity = identity;
}
}
public class GetActorReply
{
public readonly IActorRef ActorRef;
public GetActorReply(IActorRef actorRef)
{
ActorRef = actorRef;
}
}
public class Passivate // sent from child aggregate to parent coordinator
{
}
Coordinator类,对于每种聚合类型都有一个唯一的实例:
public class ActorLifetimeCoordinator r<T> : ReceiveActor where T : ActorBase
{
protected Dictionary<Identity,IActorRef> Actors = new Dictionary<Identity, IActorRef>();
protected Dictionary<Identity, List<object>> BufferedMsgs = new Dictionary<Identity, List<object>>();
public ActorLifetimeCoordinator()
{
Receive<GetActor>(message =>
{
var actor = GetActor(message.Identity);
Sender.Tell(new GetActorReply(actor), Self); // reply with the retrieved actor
});
Receive<Passivate>(message =>
{
var actorToUnload = Context.Sender;
var task = actorToUnload.GracefulStop(TimeSpan.FromSeconds(10));
// the time between the above and below lines, we need to intercept messages to the child that is being
// removed from memory - how to do this?
task.Wait(); // dont block thread, use pipeto instead?
});
}
protected IActorRef GetActor(string identity)
{
IActorRef value;
return Actors.TryGetValue(identity, out value)
? value : Context.System.ActorOf(Props.Create<T>(identity));
}
}
汇总所有聚合的基类:
public abstract class AggregateRoot : ReceivePersistentActor
{
private readonly DispatchByReflectionStrategy _dispatchStrategy
= new DispatchByReflectionStrategy("When");
protected AggregateRoot(Identity identity)
{
PersistenceId = Context.Parent.Path.Name + "/" + Self.Path.Name + "/" + identity;
Recover((Action<IDomainEvent>)Dispatch);
Command<ReceiveTimeout>(message =>
{
Context.Parent.Tell(new Passivate());
});
Context.SetReceiveTimeout(TimeSpan.FromMinutes(5));
}
public override string PersistenceId { get; }
private void Dispatch(IDomainEvent domainEvent)
{
_dispatchStrategy.Dispatch(this, domainEvent);
}
protected void Emit(IDomainEvent domainEvent)
{
Persist(domainEvent, success =>
{
Dispatch(domainEvent);
});
}
}
答案 0 :(得分:1)
这里最简单(但不是最简单)的选项是使用Akka.Cluster.Sharding模块,该模块涵盖协调器模式的各个方面,支持角色分配和整个群集的平衡。
如果您选择不需要它,遗憾的是您需要通过协调员传递消息 - 消息本身需要提供用于确定收件人的标识符。否则你最终可能会向死去的演员发送消息。