Page History
Info |
---|
At-Least-Once Delivery - 적어도 메시지를 한번 보내려는 메카니즘으로 PersistenceActor와 결합하여 목표를 달성할수 있습니다. 보낼려는 메시지가 유실될수 있는 가능성을 제거하며 적어도 한번보내려는 메카니즘으로 인해 중복 메시지 발생에 유의하여 작성 해보겠습니다해보겠습니다. |
이것은 메시지를 무조건 한번만 보내야할때 유용합니다. 아주 착한 택배 서비스 시나리오를 가정해봅시다.
택배 아저씨는 택배를 대상에게 일반적으로 아주 빠르게 대부분 성공을 하며, 물건 분실을
방지하고자 꼭 수신인 실명을 확인을 합니다. 하지만 받을사람이 부재중이라고 가정해봅시다.
택배 아저씨는 자신이 해야할 일을 하는동시에, 부재중을 체크하면서 보내려고 할것입니다.
결국 자신이 배달해야할 모든 택배를 모두 보내게 되며, 물건은 복제가 안되기때문에 중복없이
꼭 한번만 보내게 됩니다. 상대편이 선물을 받았나? 안받았나?
확인안하는 산타클로스 할아버지와는 다른 메카니즘입니다.
메시지설계
Code Block | ||||
---|---|---|---|---|
| ||||
public class Msg { public Msg(long deliveryId, string message) { DeliveryId = deliveryId; Message = message; } public long DeliveryId { get; } public string Message { get; } } public class Confirm { public Confirm(long deliveryId) { DeliveryId = deliveryId; } public long DeliveryId { get; } } public interface IEvent { } public class MsgSent : IEvent { public MsgSent(string message) { Message = message; } public string Message { get; } } public class MsgConfirmed : IEvent { public MsgConfirmed(long deliveryId) { DeliveryId = deliveryId; } public long DeliveryId { get; } } |
...
Code Block | ||||
---|---|---|---|---|
| ||||
public class ExampleDestinationAtLeastOnceDeliveryReceiveActor : ReceiveActor
{
private ILoggingAdapter log = Context.GetLogger();
protected int messageCnt = 0;
public ExampleDestinationAtLeastOnceDeliveryReceiveActor()
{
Receive<Msg>(msg =>
{
messageCnt++;
//Test를 위해 일부러 메시지를 못받은척한다.
if (messageCnt % 2 ==0)
{
log.Warning("Test for Drop Message");
return;
}
log.Debug("Yes I can");
Sender.Tell(new Confirm(msg.DeliveryId), Self);
});
}
}
public class ExampleAtLeastOnceDeliveryReceiveActor : AtLeastOnceDeliveryReceiveActor
{
private readonly IActorRef _destionationActor = Context.ActorOf<ExampleDestinationAtLeastOnceDeliveryReceiveActor>();
private ILoggingAdapter log = Context.GetLogger();
public ExampleAtLeastOnceDeliveryReceiveActor()
{
Recover<MsgSent>(msgSent => Handler(msgSent));
Recover<MsgConfirmed>(msgConfirmed => Handler(msgConfirmed));
Command<string>(str =>
{
log.Debug("received:" + str);
Persist(new MsgSent(str), Handler);
});
Command<Confirm>(confirm =>
{
//메시지 받음을 확인하고, 해당 메시지를 더이상 안보낸다.
log.Debug("received confirm:" + confirm.DeliveryId);
Persist(new MsgConfirmed(confirm.DeliveryId), Handler);
});
}
private void Handler(MsgSent msgSent)
{
Deliver(_destionationActor.Path, l => new Msg(l, msgSent.Message));
}
private void Handler(MsgConfirmed msgConfirmed)
{
ConfirmDelivery(msgConfirmed.DeliveryId);
}
public override string PersistenceId { get; } = "persistence-id";
} |
...