Versions Compared

Key

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

...

  • 장애 발생시 1분이내에 10번만 시도할수 있다. (복구 플랜)
  • 액터 작동시 널참조로인한 예외는 액터를 재시작한다재시작하여 복구한다.
  • 액터 작동시 인자값  익셉션 에러일시, 해당 액터를 Stop시킨다.


Test Plan

  • 테스트에 사용할 액터를 생성한다.  부모 : supervisor , 자식 : child1
  • child1액터에게 널 예외 유발시킨다.
  • child1액터 crash 및 복구확인
  • child1에게 메시지보내어 작동중인지 확인
  • child1액터에게 인자값 예외 유발시킨다.
  • child1가 crash가 된것 확인
  • child1에게 메시지를 보내 사살확인 


구현및 실행코드

...


Code Block
languagec#
themeEmacs
titleActor 설계
linenumberstrue
    public class Supervisor : UntypedActor
    {
        private readonly ILoggingAdapter log = Context.GetLogger();        

		//장애처리 룰을 정의합니다.
        protected override SupervisorStrategy SupervisorStrategy()
        {
            return new OneForOneStrategy(
                maxNrOfRetries: 10,	//최고 시도횟수
                withinTimeRange: TimeSpan.FromMinutes(1),	//최고 시도 시간
                localOnlyDecider: ex =>
                {
                    //  log.Info("SomeException:" );Exception별  복구전략
                    if( ex is ArithmeticException )
                        return Directive.Resume;
                    else if( ex is NullReferenceException)
                        return Directive.Restart;
                    else if (ex is ArgumentException)
                        return Directive.Stop;
                    else
                        return Directive.Escalate;                    
                });
        }
       

        protected override void OnReceive(object message)
        {
            if (message is string)
            {
                string msg = message as string;

                if ( msg.Contains("create-") )
                {
                    string childName = msg.Split('-')[1];
                    log.Info("CreateChildActor:" + childName);
                    var childActor = Context.ActorOf<Child>(childName);
                    Context.Watch(childActor);
                    Sender.Tell(childActor);
                }
                                
                
            }
        }
    }

    public class Child : UntypedActor
    {
        private int state = 0;
        private readonly ILoggingAdapter log = Context.GetLogger();

        protected override void OnReceive(object message)
        {            
            if( message is Exception)
            {
                throw message as Exception;
            }
            else if (message is int)
            {
                state = (int)message;
            }
            else if (message is string)
            {
                switch (message as string)
                {
                    case "get":
                        log.Info("Active Check");  //메시지를 받을수 있는지 체크
                        Sender.Tell(state);
                        break;
                }
            }
        }

        protected override void PreRestart(Exception reason, object message)
        {
            log.Info("Actor Restart - reason:" + reason.GetType().Name );   //액터 재시작된 이전이유를재 시작된이 야기된 이유를 , 재시작시 알수 있습니다.
        }
    }
Code Block
languagec#
themeEmacs
title실행코드
linenumberstrue
            using (ActorSystem actorSystem = ActorSystem.Create("ServiceA"))
            {
                IActorRef supervisor = actorSystem.ActorOf<Supervisor>("supervisor");
                IActorRef child = supervisor.Ask("create-child1").Result as IActorRef;

                child.Tell(new NullReferenceException() );   //강제로 예외발생...                
                Task.Delay(1000).Wait();    //복구를 기다려준다.
                child.Tell("get");

                child.Tell(new ArgumentException() );   //강제로 예외발생...
                Task.Delay(1000).Wait();    //복구를 기다려준다.
                child.Tell("get");

                Task.Delay(3000).Wait();    //종료 지연시간

            }

...