Versions Compared

Key

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

...

Code Block
languagec#
themeEmacs
linenumberstrue
collapsetrue
    // 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
languagec#
themeEmacs
linenumberstrue
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
languagec#
themeEmacs
            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));


Image Added

우리가 의도했던대로...   1 ,2 3 개씩 처리하고나서  마지막 4개는 자동으로 처리가 됩니다.