Page History
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
// received events public class SetTarget { public SetTarget(IActorRef @ref) { Ref = @ref; } public IActorRef Ref { get; } } public class Queue { public Queue(object obj) { Obj = obj; } public Object Obj { get; } } public class Flush { } // send events public class Batch { public Batch(ImmutableList<object> obj) { Obj = obj; } public ImmutableList<object> Obj { get; } } public enum State { Idle, Active } // data public interface IData { } public class Uninitialized : IData { public static Uninitialized Instance = new Uninitialized(); private Uninitialized() { } } public class Todo : IData { public Todo(IActorRef target, ImmutableList<object> queue) { Target = target; Queue = queue; } public IActorRef Target { get; } public ImmutableList<object> Queue { get; } public Todo Copy(ImmutableList<object> queue) { return new Todo(Target, queue); } } |
액터설계
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
public class ExampleFSMActor : FSM<State, IData>
{
private readonly ILoggingAdapter log = Context.GetLogger();
public ExampleFSMActor()
{
StartWith(State.Idle, Uninitialized.Instance);
When(State.Idle, state =>
{
if( state.FsmEvent is SetTarget && state.StateData is Uninitialized)
{
SetTarget target = state.FsmEvent as SetTarget;
return Stay().Using(new Todo(target.Ref, ImmutableList<object>.Empty));
}
return null;
});
When(State.Active, state =>
{
if ( (state.FsmEvent is Flush || state.FsmEvent is StateTimeout)
&& state.StateData is Todo )
{
Todo t = state.StateData as Todo;
return GoTo(State.Idle).Using(t.Copy(ImmutableList<object>.Empty));
}
return null;
}, TimeSpan.FromSeconds(1));
WhenUnhandled(state =>
{
if (state.FsmEvent is Queue && state.StateData is Todo)
{
Todo t = state.StateData as Todo;
Queue q = state.FsmEvent as Queue;
return GoTo(State.Active).Using(t.Copy(t.Queue.Add(q.Obj)));
}
else
{
log.Warning("Received unhandled request {0} in state {1}/{2}", state.FsmEvent, StateName, state.StateData);
return Stay();
}
});
OnTransition((initialState, nextState) =>
{
if (initialState == State.Active && nextState == State.Idle)
{
if (StateData is Todo)
{
Todo todo = StateData as Todo;
todo.Target.Tell(new Batch(todo.Queue));
}
else
{
// nothing to do
}
}
});
Initialize();
}
}//end class
public class FSMTestActor : UntypedActor
{
private ILoggingAdapter log = Context.GetLogger(); //기본탑재 로그
protected override void OnReceive(object message)
{
//log.Info("GetMessage:" + message.ToString());
if(message is Batch)
{
Batch batchMessage = message as Batch;
log.Info( "GetMessageCnt:" + batchMessage.Obj.Count.ToString() );
}
}
} |
테스트 수행
...
Code Block | ||||
---|---|---|---|---|
| ||||
IActorRef target = actorSystem.ActorOf<FSMTestActor>("fsmtestActor");
IActorRef fsmActor = actorSystem.ActorOf<ExampleFSMActor>("fsmActor");
fsmActor.Tell(new SetTarget(target));
fsmActor.Tell(new Queue(42));
fsmActor.Tell(new Flush());
fsmActor.Tell(new Queue(42));
fsmActor.Tell(new Queue(43));
fsmActor.Tell(new Flush());
fsmActor.Tell(new Queue(42));
fsmActor.Tell(new Queue(43));
fsmActor.Tell(new Queue(42));
fsmActor.Tell(new Flush());
fsmActor.Tell(new Queue(42));
fsmActor.Tell(new Queue(43));
fsmActor.Tell(new Queue(42));
fsmActor.Tell(new Queue(43)); |
우리가 의도했던대로... 1 ,2 3 개씩 처리하고나서 마지막 4개는 자동으로 처리가 됩니다.