스냅샷은 액터의 복구속도를 높일수가 있습니다.
SaveSnapShot을 호출하여 내부상태의 스냅샷을 저장할수가 있습니다.
다음과 같은 메시지액터를 설계한다고 합시다.
- 단순하게 문자열 메시지만 전송받습니다.
- 액터가 종료되더라도 최근 50개의 메시지를 복구합니다.
- 테스트코드에서는 100개의 메시지를 보내고 , 액터를 죽인후 다시 뛰워 복구가되는지 살펴봅니다.
public class MySnapShotActor : UntypedPersistentActor { private ILoggingAdapter log = Context.GetLogger(); public override string PersistenceId => "my-stable-persistence-id"; private const int SnapShotInterval = 5; //스냅샷은 5의 배수에 저장합니다. private object state = new object(); //복구수 전략을 선택합니다. (최근 50개) public override Recovery Recovery => new Recovery(fromSnapshot: new SnapshotSelectionCriteria(minSequenceNr:0, maxSequenceNr: 50, maxTimeStamp: DateTime.UtcNow)); //public override Recovery Recovery => new Recovery(fromSnapshot: SnapshotSelectionCriteria.None); protected override void OnRecover(object message) { // handle recovery here if (message is SnapshotOffer offeredSnapshot) { log.Debug("이전 스냅샷 복구"); state = offeredSnapshot.Snapshot; } else if (message is RecoveryCompleted) { log.Debug("스냅샷복구완료:"); } else { // event log.Debug("스냅샷e:" + message); } } protected override void OnCommand(object message) { if (message is SaveSnapshotSuccess s) { log.Debug("스냅샷 성공"); } else if (message is SaveSnapshotFailure f) { log.Debug("스냅샷 실패"); } else if (message is string cmd) { log.Debug("cmd:" + cmd); Persist($"evt-{cmd}", e => { UpdateState(e); if (LastSequenceNr % SnapShotInterval == 0 && LastSequenceNr != 0) { log.Debug("스냅샷 시도"); SaveSnapshot(state); } }); } } private void UpdateState(string evt) { state = evt; } }
var actorInfo = Props.Create<MySnapShotActor>(); var myactor = actorSystem.ActorOf(actorInfo, "myActor"); for(int i = 0; i < 100; i++) { string message = "t" + i; myactor.Tell(message); } waitForTest(1000); myactor.Tell(Akka.Actor.Kill.Instance, ActorRefs.NoSender); waitForTest(1000); //액터가 복구되는지 확인합니다. myactor = actorSystem.ActorOf(actorInfo, "myActor");
스냅샷은 다양한 저장소에 저장이 가능합니다.
참고 url : https://petabridge.com/blog/intro-to-persistent-actors/