보라코딩

Day 22, Akka 본문

개발자가 되었다?

Day 22, Akka

new 보라 2023. 9. 14. 18:52

akka 너무 어렵다ㅎㅎㅎ

 

Actor

  • 상태를 가짐
  • 메세지를 받음
  • 한 번에 하나의 메시지를 처리

 

Actor Model

 

  • 액터는 메세지로만 소통
  • 최소 단위는 액터
  • 메시지는 불변
  • 액터는 새 액터 만들 수 있음 (메시지로 처리)
  • 계층 구조로 액터 만든다
  • 액터는 다음 메시지 처리를 위한 상태 변경 가능

 

Actor 구성

 

  • Mailbox : actor 시스템으로 전달 받은 메시지를 FIFO로 처리
  • Behavior : 호출된 함수 수행. 직접 호출 불가
  • State : 멤버 변수. 상태 공유 불가 (public으로 해도 액터 직접 접근 불가)
  • SupervisorStrategy : 자식 장애 처리. (액터는 계층 구조 갖고, 계층 구조 통해 자식 액터를 부모 액터가 담당)
  • Children : 자신 중심으로 계층 구조 접근

 

Actor System

  • 사용자 정의 액터들 간의 메세지 전달 담당
  • 사용자 정의 액터는 "user guardian actor(/user)" 자식으로만 생성
  • System guardion actor(/system) 액터는 액터 시스템이 생성되면 자동으로 생성
ActorSystem system = ActorSystem.Create("...");
system.Terminate();



간단한 Akka example

Program.cs

using Akka.Actor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Actor2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // ActorSystm 생성
            ActorSystem MyActorSystem = ActorSystem.Create("MyActorSystem");

            PrintInstructions();

            // Actor 생성
            var consoleWriterActor = MyActorSystem.ActorOf(Props.Create(() => new ConsoleWriteActor()));
            var consoleReaderActor = MyActorSystem.ActorOf(Props.Create(() => new ConsoleReaderActor(consoleWriterActor))); // Reader가 Write에 메세지 보낼 수 있다

            // start 메시지 보내기 (콘솔에서 입력 시작하라는 지시)
            consoleReaderActor.Tell("start"); 

            // 액터시스템이 종료될 때까지 메인 스레드가 종료 되는 것을 차단
            MyActorSystem.WhenTerminated.Wait();

        }

        private static void PrintInstructions()
        {
            Console.WriteLine("Write whatever you want into the console!");
            Console.Write("Some lines will appear as");
            Console.ForegroundColor = ConsoleColor.DarkRed;
            Console.Write(" red~~ ");
            Console.ResetColor();
            Console.Write(" and others will appear as");
            Console.ForegroundColor = ConsoleColor.Green;
            Console.Write(" green~~ ");
            Console.ResetColor();
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("Type 'exit' to quit this application at any time! \n");

        }
    }
}

 

ConsoleWriteActor.cs

using Akka.Actor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Actor2
{
    internal class ConsoleWriteActor : UntypedActor
    {
        // 수신한 메시지를 콘솔에 출력
        protected override void OnReceive(object message)
        {
            var msg = message as string;

            if(string.IsNullOrEmpty(msg))
            {
                Console.ForegroundColor = ConsoleColor.DarkYellow;
                Console.WriteLine("Please provide an input. \n");
                Console.ResetColor();
                return;
            }

            var even = msg.Length % 2 == 0;
            var color = even ? ConsoleColor.Red : ConsoleColor.Green;
            var alert = even ? "Your string had an even # of characters. \n" : "Your string has an odd # of characters. \n";

            Console.ForegroundColor = color;
            Console.WriteLine(alert);
            Console.ResetColor();
        }
    }
}

 

ConsoleReaderActor

using Akka.Actor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Actor2
{
    internal class ConsoleReaderActor : UntypedActor
    {
        public const string ExitCommand = "exit";
        private IActorRef _consoleWriterActor;

        public ConsoleReaderActor(IActorRef consoleWriterActor)
        {
            _consoleWriterActor = consoleWriterActor;
        }

        // 액터가 메세지 수신할 때마다 호출
        protected override void OnReceive(object message)
        {
            var read = Console.ReadLine();

            if (!string.IsNullOrEmpty(read) && String.Equals(read, ExitCommand, StringComparison.OrdinalIgnoreCase))
            {
                Context.System.Terminate();
                return;
            }

            _consoleWriterActor.Tell(read);
            Self.Tell("continue");
        }
    }
}

'개발자가 되었다?' 카테고리의 다른 글

Day 24, JS  (0) 2023.09.18
Day 23, RabbitMQ  (0) 2023.09.15
Day 21, EF Core  (0) 2023.09.13
Day 20, C#  (0) 2023.09.12
Day 19, C# _ Unit Test  (0) 2023.09.11