Versions Compared

Key

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

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

기본 처리 메스드를 재정의하여 기본 메시지 처리외에 커스텀한 기능을 부여할수 있습니다부여할시 사용됩니다.

이번장에서는 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

...

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

...

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

액터종료방법

...

Stop

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

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

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

PoisonPill

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

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

안전한 액터 종료(Graceful Stop)

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

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

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

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


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
Code Block
languagebash
themeEmacs
linenumberstrue
var manager = system.ActorOf<Manager>();

try
{
    await manager.GracefulStop(TimeSpan.FromMilliseconds(5), "shutdown");
    // the actor has been stopped
}
catch (TaskCanceledException)
{
    // the actor wasn't stopped within 5 seconds
}

...
public class Manager : UntypedActor
{
    private IActorRef worker = Context.Watch(Context.ActorOf<Cruncher>("worker"));

    protected override void OnReceive(object message)
    {
        switch (message)
        {
            case "job":
Setup();
        }

        public void worker.Tell("crunch");Setup()
        {
        break;
    //테스트 관찰자..
       case Shutdown s:
   probe = this.CreateTestProbe();

           worker.Tell(PoisonPill.Instance, Self); //하위GraceFulDown을 worker의위한 작동을Manager액터 중지시킵니다.생성
            manager = Sys.ActorOf(Props.Create(() => new Context.Become(ShuttingDownTestManager(probe)));
            
    break;    }

        }[Theory(DisplayName = "GracefulStopTest")]
    }

    [InlineData(5)]
        public privateasync voidTask ShuttingDownGtaceFulStopAreOK(objectint messagewaitTimeSec)
    {
    {
    switch (message)
        {
  //Step:
          case "job": //어떤 잡을1.GracefulStop 시키려고을통한 할시,셧다운중임을 알립니다.
  종료 시그널 발생 
            //  Sender.Tell("service unavailable, shutting down", Self);
2.자식 액터종료(PoisonPill, 지금까지 받은메시지까지만 처리하고)
            // 3.GracefulStop , Terminated 될때까지 break;대기
            case// Terminated검증 t:
 안전한 종료메시지가 왔는지 검사

            await Context.Stop(Selfmanager.GracefulStop(TimeSpan.FromMilliseconds(3), "shutdown");

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







액터접근 주소체계

...


잠시

실습없이, Actor를 접근하는 주소체계에대해 설명 드리겠습니다.  ActorPath는   ActorPath는 총 4가지로 구분이 되며 http의 되며  http의 RestAPI의 주소체계와 거의 흡사하다고 볼수 있습니다.

...

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

...