Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagec#
themeEmacs
linenumberstrue
 public class MySnapShotActor : UntypedPersistentActor
{
    private ILoggingAdapter log = Context.GetLogger();
    public override string PersistenceId => "my-stable-persistence-id";
    private const int SnapShotInterval = 52;  //스냅샷은2의 5의배수에 배수에스냅샷을 저장합니다.
    private object state = new object();

    //실시간 복구수 전략을 선택합니다. (최근 50개최근5개)
    public override Recovery Recovery => new Recovery(fromSnapshot: new SnapshotSelectionCriteria(minSequenceNr:0, maxSequenceNr: 505, maxTimeStamp: DateTime.UtcNow));
    //public override Recovery Recovery => new Recovery(fromSnapshot: SnapshotSelectionCriteria.NoneLatest);

    protected override void OnRecover(object message)
    {
        // handle recovery here
        if (message is SnapshotOffer offeredSnapshot)
        {
            log.Debug("이전마지막 스냅샷 복구");
            state = offeredSnapshot.Snapshot;
            log.Debug("스냅샷복구완료:" + state);
        }
        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;
    }
}
Code Block
languagec#
themeEmacs
linenumberstrue
var actorInfo = Props.Create<MySnapShotActor>();
var myactor = actorSystem.ActorOf(actorInfo, "myActor");
for(int i = 0; i < 1005; 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");
Expand
titleresult

......중간생략( 0-99까지 5까지 메시지 전송하고, 액터를 죽이고 다시살림)

...... 복구과장 ( 최근 50개의 메시지가 복구가됩니다복구과정 ( 마지막 상태가 복구가됩니다. , 2의배수에서만 스냅샷 저장했으니, 3+1에해당하는 t3이 복구됩니다. )

[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t87
[DEBUG][2017-09-25 오후 12:59:211:53:25][Thread 00130025][[akka://ServiceA/user/myActor#160404237myActor#1899122464]] 스냅샷e:evt-t88이전 스냅샷 복구
[DEBUG][2017-09-25 오후 121:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t89
[DEBUG][2017-09-25 오후 12:59:2153:25][Thread 00130025][[akka://ServiceA/user/myActor#160404237myActor#1899122464]] 스냅샷e스냅샷복구완료:evt-t90
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t91
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t92
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t93
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t94
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t95
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t96
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t97
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t98
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷e:evt-t99
[DEBUG][2017-09-25 오후 12:59:21][Thread 0013][[akka://ServiceA/user/myActor#160404237]] 스냅샷복구완료:t3

위 테스트는 어플리케이션을 껏다가 켜도, 액터의 마지막 상태가 복원이 됩니다.

Store Plugin

스냅샷은 다양한 저장소에 저장이 가능하며,  akka.config에서 지정가능합니다.

...

Panel
title설정예

akka.persistence.journal.inmem {
class = "Akka.Persistence.Journal.MemoryJournal, Akka.Persistence"
# Dispatcher for the plugin actor.
plugin-dispatcher = "akka.actor.default-dispatcher"
}

akka.persistence.snapshot-store.inmem {
# Class name of the plugin.
class = "Akka.Persistence.Snapshot.MemorySnapshotStore, Akka.Persistence"
# Dispatcher for the plugin actor.
plugin-dispatcher = "akka.actor.default-dispatcher"
}

akka.persistence.snapshot-store.local {
# Class name of the plugin.
}


별다른설정이없으면, 파일에 저장이 됩니다. 

Image Added


참고 url : https://petabridge.com/blog/intro-to-persistent-actors/

...