Actor메시지는 일반적으로 보낸순서에의한 순서가 보장이 되지만 MailBox의 경우 동시에 보낸 메시지중

우선으로 처리해야할 메시지에대해 정의가 가능합니다.

덜바쁜 녀석에게 작업을 분배한다던지, 메시지 자체에 우선순위를 높일수 있습니다.

라운드로빈의 한계와 균등의 문제 해결하기

앞장에서 프린터 액터를 구성하면서, 기본적이고 익숙한 라운드로빈 라우터를 사용해보았습니다.

smallest-mailbox-pool은 덜바쁜 아이(라우티)에게 작업분배를 우선적으로 하는 심플한 라우터입니다.

작업완료시간이 일정하지 않을때, 라운드로빈은 균등의 문제를 해결하지 못할수 있을때 사용가능합니다.


그림:smallest-mailbox-pool
Routee3는 바쁘기때문에, 쉬게 해줘야합니다.
akka.actor.deployment {
  /some-pool {
    router = smallest-mailbox-pool
    nr-of-instances = 5
  }
}



메시지 우선순의 정의하기

메시지 우선순위를 정의하여 ( 보안결함 vs 버그)  5개의 메시지를(IsBug,IsSecurityFlaw,IsBug,IsBug,IsSecurityFlaw) 한꺼번에 전송해보겠습니다.

기대 결과는 보안결함 두개의 메시지가 먼저 처리되는것이며, 유닛테스트 코드를 통해 작동방법과 결과를 알수있습니다.

akka.conf
# 우선순위 메시지는 낮은숫자가 우선이며 심플하게 정의가능합니다.
# code :  https://github.com/psmon/AkkaForNetCore/blob/master/AkkaNetCore/Models/Message/IssueTrackerMailbox.cs
# 메일박스 룰 전체 네임스페이스명과,어셈블리명(보통 프로젝트명) 을 참조합니다.
my-custom-mailbox {
    mailbox-type : "AkkaNetCore.Models.Message.IssueTrackerMailbox, AkkaNetCore"
}

actor.deployment {
    /mymailbox {
        mailbox = my-custom-mailbox
    }
}
using System;
using Akka.Actor;
using Akka.TestKit;
using AkkaNetCore.Models.Message;
using Xunit;
using Xunit.Abstractions;

namespace AkkaNetCoreTest.Actors
{
    public class MailBoxTest : TestKitXunit
    {
        protected TestProbe probe;
        protected IActorRef mailBoxActor;

        public MailBoxTest(ITestOutputHelper output) : base(output)
        {
            // 이 테스트를 위한 akkaconfig는 다음에 설정되어있습니다.
            // TestKitXunit
            // TestKitXunit.akkaConfig  : 메일박스 설정
            Setup();
        }

        public void Setup()
        {
            //여기서 관찰자는 Qa 알림 역활을 받습니다.
            probe = this.CreateTestProbe();            
            var mailboxOpt = Props.Create<MailBoxActor>(probe).WithMailbox("my-custom-mailbox");
            mailBoxActor = Sys.ActorOf(mailboxOpt, "mymailbox");

        }

        [Fact]
        public void 보안결함_메시지가_먼저처리_되어야한다()
        {
            // isBug가 false인 보안결함 메시지가 먼저 처리되어야합니다.
            Issue msg1 = new Issue("test1", true);
            Issue msg2 = new Issue("test2", false);
            Issue msg3 = new Issue("test3", true);
            Issue msg4 = new Issue("test4", true);
            Issue msg5 = new Issue("test5", false);
            mailBoxActor.Tell(msg1);
            mailBoxActor.Tell(msg2);
            mailBoxActor.Tell(msg3);
            mailBoxActor.Tell(msg4);
            mailBoxActor.Tell(msg5);

            for(int i = 0; i < 5; i++)
            {
                probe.ExpectMsg<Issue>(issue =>
                {
                    Console.WriteLine($"IssueInfo : Message:{issue.Message} IsSecurityFlaw:{issue.IsSecurityFlaw} IsBug:{issue.IsBug} ");
                });
            }
            /* 기대결과
            IssueInfo: Message: test2 IsSecurityFlaw:True IsBug:False
            IssueInfo : Message: test5 IsSecurityFlaw:True IsBug:False
            IssueInfo : Message: test4 IsSecurityFlaw:False IsBug:True
            IssueInfo : Message: test3 IsSecurityFlaw:False IsBug:True
            IssueInfo : Message: test1 IsSecurityFlaw:False IsBug:True
            */
        }
    }

    public class MailBoxActor : ReceiveActor
    {
        IActorRef notifyQa;
        public MailBoxActor(IActorRef _notifyQa)
        {
            notifyQa = _notifyQa;
            //MailBoxTest
            Receive<Issue>(issue => {                
                //Console.WriteLine($"IssueInfo : Message:{issue.Message} IsSecurityFlaw:{issue.IsSecurityFlaw} IsBug:{issue.IsBug} ");
                notifyQa.Tell(issue);
            });
            //InboxTest
            Receive<string>(msg =>
            {
                if (msg == "hello")
                    Sender.Tell("world");
            });
        }
    }
}



  • No labels