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"; } |
TestCode
테스트 케이스
- 메시지 10개를 한꺼번에 보낸다.
- 받는 쪽에서 짝수번째 메시지를 못본채한다.( test 시나리오)
- 우선 홀수 메시지는 모두 전송됨을 확인
- 메시지 전송에 실패가난 짝수번째 메시지도 다시전송하여 결국 성공시킨다.(홀수번쨰 성공)
Code Block | ||||
---|---|---|---|---|
| ||||
var actorInfo = Props.Create<ExampleAtLeastOnceDeliveryReceiveActor>();
var myactor = actorSystem.ActorOf(actorInfo, "myActor");
for(int i=0;i<10;i++)
myactor.Tell("can you speak english?"); |
Expand | ||
---|---|---|
| ||