Versions Compared

Key

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

...

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() );
            }

        }
    }


테스트 수행

Flush란 : 메시지큐를  비운다란 의미보다, 비동기적으로 적재된 메시지를 처리를 하겠다란 의미입니다. 

테스트 의도:

  • 메시지를 하나만 보내고, 수동 처리(Flush) 를 한다.
  • 메시지를 두개 보내고 , 수동 처리(Flush)한다.
  • 메시지를 4개보내고 한꺼번에 자동으로 처리되는지 확인한다.


...

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));


Code Block
themeEmacs
    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() );
            }
        }
    }

배치처리를 위한 액터는 단지 리스트를 받으면 한꺼번에 처리를 진행하면 되며

순수한 배치처리를 위한 도메인 로직만을 신경 쓰면되겠습니다.


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

여기서 Count를 알수 있다란 의미는, 불특정하게 발생한 이벤트를 우리가 의도한 룰대로 모아서

리스트 형태의 데이터로 일괄 처리할수 있습니다.


Note

위 기능이 사용되면 좋은곳

  • 불규칙적으로 발생하는 대용량 인입 저장의 성능 향상
  • 대용량 인입처리의 분산처리화
  • 기타등등