Versions Compared

Key

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

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

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

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

Image Added

우선순위 정의 코드

...


Code Block
languagec#
themeEmacs
titleIssue라는 메시지에 IsSecurityFlaw 참인 조건을 우선처리
linenumberstrue
using Akka.Actor;
using Akka.Event;
using Akka.Dispatch;    

//namespace ServiceA.STUDY
	public class Issue
    {
        public bool IsSecurityFlaw;
        public bool IsBug;
        public string Message;

        public Issue(string message, bool isBug)
        {
            Message = message;
            IsBug = isBug;
            IsSecurityFlaw = !isBug;
        }

    }

    public class IssueTrackerMailbox : UnboundedPriorityMailbox
    {        
        public IssueTrackerMailbox(Settings setting , Akka.Configuration.Config config) : base(setting, config)
        {            
        }
        

        protected override int PriorityGenerator(object message)
        {
            var issue = message as Issue;

            if (issue != null)
            {
                if (issue.IsSecurityFlaw)
                    return 0;

                if (issue.IsBug)
                    return 1;
            }

            return 2;
        }
    }


PriorityGenerator 에서 우선순위를 조정합니다.


Actor 설계

...

Code Block
languagec#
themeEmacs
linenumberstrue
    public class MailBoxActor : ReceiveActor
    {
        private ILoggingAdapter log = Context.GetLogger();

        public MailBoxActor()
        {
            //MailBoxTest
            Receive<Issue>(issue => {
                log.Info("IssueInfo : Message:{0} IsSecurityFlaw:{1} IsBug:{2} ", issue.Message, issue.IsSecurityFlaw, issue.IsBug);
            });

            //InboxTest
            Receive<string>(msg =>
            {
                if (msg == "hello")
                    Sender.Tell("world");
            });
        }

    }



정의코드를 사용하기위한 설정

...


No Format
#특정한 액터에 MailBox 메시지 처리기를 사용하겠다고 설정을 합니다.


my-custom-mailbox {
              mailbox-type : "ServiceA.STUDY.IssueTrackerMailbox, ServiceA"
            }


actor.deployment {
                /mymailbox {
                mailbox = my-custom-mailbox
                }
              }


실행코드

...


Code Block
languagec#
themeEmacs
linenumberstrue
            var mailboxOpt = Props.Create<MailBoxActor>().WithMailbox("my-custom-mailbox");
            var actor = actorSystem.ActorOf(mailboxOpt, "mymailbox");
            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);
            actor.Tell(msg1);
            actor.Tell(msg2);
            actor.Tell(msg3);
            actor.Tell(msg4);
            actor.Tell(msg5);
Expand
titleResult

Image Added


 다양한 이슈를 썩어서 동시에 보냈지만,  IsSecurityFlaw=true 인 메시지를 우선 처리하게 됩니다.

동시성 처리에 있어서 가급적 우선이란 의미가 맞을듯 하며 , 어느 외부적요인 혹은 동시성이 달라서

메시지 순서가 변경된다고 해도, 서비스에 이상이생기는 설계는 하지 말아야 할것입니다.


INBOX

...


Tip

액터들과의 소통에서, ask패턴은 해결책이 될수 있지만, 할수 없는 작업이 두가지가 있습니다.

여러 액터들로부터 요청한 메시지 다중으로 회신기다리기 ( 물론 어떠한 작업 두가지가 완료되었을시 어떠한

메시지를 보내는 액터를 설계할수는 있지만, 한 코드 스콥에서 해결하기가 어렵습니다.)

Code Block
languagec#
themeEmacs
linenumberstrue
            var target = actorSystem.ActorOf<MailBoxActor>("inboxactor");
            var inbox = Inbox.Create(actorSystem);            

            try
            {
                ///// Sample 1 : 특정 메시지를 받는지 여부
                inbox.Send(target, "hello");
                bool result = inbox.Receive(TimeSpan.FromSeconds(1)).Equals("world");
                Console.WriteLine("result:" + result);

                //// Sample 2 : 관리대상 target이 종료되는지 여부...
                inbox.Watch(target);    //해당 액터를 inbox에서 감시
                target.Tell(PoisonPill.Instance, ActorRefs.NoSender);
                if( inbox.Receive(TimeSpan.FromSeconds(1)) is Terminated)
                {
                    Console.WriteLine("target 종료됨..");
                }                

            }
            catch (TimeoutException)
            {
                Console.WriteLine("TimeOut");
            }

이경우 Inbox 를 사용하여,  복수의 Actor의 요청결과를 묶어낼수 있습니다.