Versions Compared

Key

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

  Untyped Actor는UntypedActor는, 이전 섹션에서 익힌 ReceiveActor 처럼 생성자에서 Type매칭에의해 메시지 처리기를 등록하는게 아닌 ,

OnReceive에서 직관적으로 수신처리 가능코드를 작성합니다기본 처리 메스드를 재정의하여 기본 메시지 처리외에 커스텀한 기능을 부여할시 사용됩니다.

이번장에서는 Actor의 기능을 확장하여 유용한 몇가지 기능들을 살펴보겠습니다.

...



OnReceive - 기본 메시지 처리 재정의

Code Block
languagec#
themeEmacs
titleUntyped Actor
linenumberstrue
    public class MyActorSame : UntypedActor
    {        
        protected override void OnReceive(object message)
        {
            if(message is string)
            {
                if (message as string == "createChild")
                {
                    Context.ActorOf<MyActor>("myChild");
                    Sender.Tell("Create Child Succed:myChild");
                }
                else
                {
                    Sender.Tell("RE:" + message);
                }
            }
            else if(message is SomeMessage)
            {
                Sender.Tell("RE:" + (message as SomeMessage).message );
            }
        }
    }

...

메시지수신부 OnReceive 를 직접 Override해서 사용하는것 외에는 차이가 없습니다없으며

아래에 설명된 확장 기능들은 모두 ReceveActor에서도 사용가능합니다.


Become/Unbecome

...

  사용목적 : 메시지 처리기가 어떠한 상태에따라 다른 메시지 처리기가 필요하다고 가정합시다.

...

Expand
titleResult

[INFO][2017-09-06 오전 4:53:45][Thread 0006][[akka://ServiceA/user/myactor#14600
16350]] BasicActor:GetSomeMessage 나는 살아있다.

[INFO][2017-09-06 오전 4:53:45][Thread 0004][[akka://ServiceA/user/watcher#11499
84538]] WatchActor:GetSomeMessage <Terminated>: [akka://ServiceA/user/myactor#14
60016350] - ExistenceConfirmed=True

[INFO][2017-09-06 오전 4:53:45][Thread 0004][[akka://ServiceA/user/watcher#11499
84538]] 감시대상이 사라짐

...


Forward message

Image Removed

잠시 실습없이, Actor를 접근하는 주소체계에대해 설명 드리겠습니다.  ActorPath는 총 4가지로 구분이 되며 

http의 RestAPI의 주소체계와 거의 흡사하다고 볼수 있습니다.

...

No Format
target.Forward(result, Context);


tatget : 다른 액터
Context : me

다른액터로 받은 메시지를 전달할때 사용합니다.  이것은 라우터,로드밸런스,복제 등에서 유용하게 쓰입니다.

액터종료방법

...

Stop

No Format
Context.Stop(child);
actorSystem.Stop(child);

 동일한 System내에서, 또는 자신이 가지고 있는 하위 액터중

자신의 하위액터를 중지 시킵니다.

PoisonPill

No Format
myActor.Tell(PoisonPill.Instance, Sender);

메시지를 통해 액터를 멈추고자 할때 이용됩니다. 일반적이고 안정적입니다.


Killing

No Format
// kill the 'victim' actor
victim.Tell(Akka.Actor.Kill.Instance, ActorRef.NoSender);

Kill메시지는  액터를 ActorKilledException를 발생 강제로 죽여서, 액터를 죽입니다.

그리고 관리자에게 액터를 다시 시작시킬것인가 혹은 종료시킬것인가? 의 설정을 통해 다음 종료전략이 실행됩니다.


GracefulStop

No Format
await manager.GracefulStop(TimeSpan.FromMilliseconds(5), "shutdown");



안전한 액터 종료(Graceful Stop)

...

 관리자 액터가 , 어떠한 액터를 감시하고있고, 모두 안전하게 종료후 자기자신도 마지막에

안전하게 종료할시 사용됩니다. 여기서 안전하다란 종료는 어플리케이션 레벨에서 설계해야하며

GracefulStop()은 종료시도와함께, 종속된 Actor( Watch에 등록된)가 모두 종료되었는가를 확인할수 있습니다. 

이것은 안전한 어플리케이션 종료시에 활용이됩니다.


Code Block
languagebash
themeEmacs
linenumberstrue
using Akka.Actor;
using Akka.TestKit;
using AkkaDotModule.ActorSample;
using AkkaNetCoreTest;
using System;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;

namespace TestAkkaDotModule.TestActors
{
    public class HelloActor2 : ReceiveActor
    {        
        private string MyName { get; set; }

        private IActorRef target = null;

        public HelloActor2(string name)
        {
            MyName = name;

            ReceiveAsync<string>(async message =>
            {
                string inComeMessage = $"[{MyName}] : {message}";

            });

        }
    }

    public class TestManager : UntypedActor
    {
        IActorRef probe;

        private IActorRef worker = Context.Watch(Context.ActorOf(
            Props.Create(() => new HelloActor2("hello")), "worker" ));

        public TestManager(IActorRef _probe)
        {
            probe = _probe;
        }

        protected override void OnReceive(object message)
        {
            switch (message)
            {
                case "hello":
                    worker.Tell("hello");
                    break;
                case "shutdown":                    
                    worker.Tell(PoisonPill.Instance, Self);
                    Context.Become(ShuttingDown);   //종료모드로 메시지처리 상태변경
                    break;                
            }
        }

        private void ShuttingDown(object message)
        {
            switch (message)
            {
                case "hello": //어떤 잡을 시키려고 할시,셧다운중임을 알립니다.
                    Sender.Tell("service unavailable, shutting down", Self);
                    break;
                case Terminated t:
                    probe.Tell("SafeClose");
                    Context.Stop(Self);
                    break;
            }
        }
    }

    public class LifeCycleActorTest : TestKitXunit
    {
        protected TestProbe probe;

        protected IActorRef manager;

        public LifeCycleActorTest(ITestOutputHelper output) : base(output)
        {
            Setup();
        }

        public void Setup()
        {
            //테스트 관찰자..
            probe = this.CreateTestProbe();

            //GraceFulDown을 위한 Manager액터 생성
            manager = Sys.ActorOf(Props.Create(() => new TestManager(probe)));
            
        }

        [Theory(DisplayName = "GracefulStopTest")]
        [InlineData(5)]
        public async Task GtaceFulStopAreOK(int waitTimeSec)
        {
            //Step:
            // 1.GracefulStop 을통한 종료 시그널 발생 
            // 2.자식 액터종료(PoisonPill, 지금까지 받은메시지까지만 처리하고)
            // 3.GracefulStop , Terminated 될때까지 대기
            // 검증 : 안전한 종료메시지가 왔는지 검사

            await manager.GracefulStop(TimeSpan.FromMilliseconds(3), "shutdown");

            probe.ExpectMsg("SafeClose", TimeSpan.FromSeconds(waitTimeSec));
        }
    }
}







액터접근 주소체계

...


Image Added

  ActorPath는 총 4가지로 구분이 되며  http의 RestAPI의 주소체계와 거의 흡사하다고 볼수 있습니다.

여기서 Protocol,여기서 Protocol,ActorSystem,Address 요소를 생략하면 ex>'user/actorName1'  자신의 LocalSystem에만 접근하겠다란 의미입니다.

...

  • RESTAPI 호출 VS RemoteActor 호출
  • 항상 DB Read 가 발생하는 RESTAPI VS Actor를 사용하여 DB Read가 발생하지않는 없는 RESTAPI
  •  
    Jira
    serverJIRA
    serverIdfeb819c4-adfb-3d6d-aaee-7d42f588dbbe
    keyAKKADOCU-8

...