Page History
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
using System.Collections.Immutable;
using Akka.Persistence;
#region MessageData
public class Shutdown { }
//커멘드와 이벤트를 분리합니다. 커멘드는 이벤트를 발생시키는 명령이며
//1 커멘드는 n개의 이벤트로 복제가 될수 있습니다.
public class Cmd
{
public Cmd(string data)
{
Data = data;
}
public string Data { get; }
}
public class Evt
{
public Evt(string data)
{
Data = data;
}
public string Data { get; }
}
public class ExampleState
{
private readonly ImmutableList<string> _events;
public ExampleState(ImmutableList<string> events)
{
_events = events;
}
public ExampleState() : this(ImmutableList.Create<string>())
{
}
public ExampleState Updated(Evt evt)
{
return new ExampleState(_events.Add(evt.Data));
}
public int Size => _events.Count;
public override string ToString()
{
return string.Join(", ", _events.Reverse());
}
}
#endregion
#region Actor
public class PersistentActor : UntypedPersistentActor
{
private ExampleState _state = new ExampleState();
private void UpdateState(Evt evt)
{
_state = _state.Updated(evt);
}
private int NumEvents => _state.Size;
public override Recovery Recovery => new Recovery(fromSnapshot: SnapshotSelectionCriteria.None);
protected override void OnRecover(object message)
{
switch (message)
{
case Evt evt:
UpdateState(evt);
break;
case SnapshotOffer snapshot when snapshot.Snapshot is ExampleState:
_state = (ExampleState)snapshot.Snapshot;
break;
}
}
protected override void OnCommand(object message)
{
switch (message)
{
case Cmd cmd:
Persist(new Evt($"{cmd.Data}-{NumEvents}"), UpdateState);
Persist(new Evt($"{cmd.Data}-{NumEvents + 1}"), evt => //이코드는 복제와 추가행동 전략과 관련있습니다.
{
UpdateState(evt);
Context.System.EventStream.Publish(evt);
});
break;
case "snap":
SaveSnapshot(_state);
break;
case "print":
Console.WriteLine("Try print");
Console.WriteLine(_state);
break;
case Shutdown down:
Context.Stop(Self);
break;
}
}
public override string PersistenceId { get; } = "sample-id-1"; //영속성을 위한 고유한 아이디값을 가집니다.
}
#endregion |
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
var actorInfo = Props.Create<PersistentActor>(); var perActor = actorSystem.ActorOf(actorInfo, "myActor"); // usage Cmd cmd1 = new Cmd("장바구니를 염물건을 담음-1"); Cmd cmd2 = new Cmd("장바구니에 물건을 담음-2"); Cmd cmd3 = new Cmd("장바구니에 물건을 또담음-3"); Cmd cmd4 = new Cmd("장바구니에 처음 담은 물건을뺌-4"); perActor.Tell(cmd1); perActor.Tell(cmd2); perActor.Tell(cmd3); perActor.Tell(cmd4); perActor.Tell("print"); //현재까지 액터가 가진 이벤트리스트를 재생합니다. waitForTest(1000); //액터를 강제로 죽입니다. perActor.Tell(Akka.Actor.Kill.Instance, ActorRefs.NoSender); waitForTest(1000); //액터가 복구되는지 확인합니다. perActor = actorSystem.ActorOf(actorInfo, "myActor"); perActor.Tell("print"); |
Expand | ||
---|---|---|
| ||
[DEBUG][2017-09-24 오후 1:59:13][Thread 0009][EventStream(ServiceA)] Logger log1-DefaultLogger [DefaultLogger] started |
위 설계 코드를 테스트하는 코드는 간단합니다. 우리는 어떠한 커멘드를 비 동기로 보내고,
...