Page History
Info |
---|
ReceiveActor은 Actor의 기본 메시지 처리기가 정의된 기본 클래스이며 대부분의 기본 메시지처리는 ReceiveActor에서 가능합니다. 액터모델의 특징 요약
ActorSystem 주요 메서드
Actor 메시지 전송 주요 메서드
|
Actor 정의(+메시지설계)
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
public class SomeMessage { public string message { set; get; } } public class MyActor : ReceiveActor { public MyActor() { Receive<string>(message => { Sender.Tell("RE:" + message); }); Receive<SomeMessage>(message => { Sender.Tell("RE:" + message.message); }); } } |
Actor의 는 Actor는, 메시지를 유연하게 보낼수 있는 가장작은 기본객체이며 송수신 정의하는 가장작은 객체의 정의 이며, 능동적 객체라고 볼수 있다.
Actor설계시 기본적으로 다음을 고려한다우리는 Actor설계시다음을 생각하면 된다. 이것은 마치 특정API 설계시 하는 고민과 똑같다.
- 어떠한 메시지(구조체)를 전달할것인가?
- 특정한 메시지(요청)에 어떻게 반응할것인가?
위 정의 코드는 그러한 설계에대해 구현을 한것이다.
...
한것이며, 다음과 같은 스펙을 가진다.
- 메시지를 받게 될시 , 접두어 "RE:" 를 붙여 해당 메시지를 그대로 돌려줘라
돌려줌 - 응답해야할 Type이 정해지지 않고 다양한 요청에 대해 다양한 Type으로 응답가능
위 코드에서 ReceiveActor 생성자에서 , Type 생성자에서 , 패턴 매칭하여 메시지 처리기가 가능한것은 , ReveiveActor의 Receive의 추상화덕분이며
IF문이나 스위치문없이 생성자에서 , 처리할 패턴별로 처리기가 등록이 가능한것은 C#의 문법지원때문인데
개발 언어학 적으로 C# 언어학적으로 파악하고자 하면 ( 템플릿 람다 /함수형/ 델리게이트 특성) 등 참조 참조하여 심화 학습이 가능합니다.
어쨋든, 우리는 아주 우리의 아주 짧은 코드로 액터 메시지 처리기 설계가 끝이났습니다.
...
액터 메시지 처리기 설계가 끝이 났습니다.
액터 생성
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
protected void SomeTest1()
{
IActorRef myActor = actorSystem.ActorOf<MyActor>("myactor");
Console.WriteLine(myActor.Ask("Hello Akka").Result);
} |
Expand | ||
---|---|---|
| ||
RE:Hello AKKA |
처음에 설계한 MyActor를 myActor란 이름으로 생성하고
Heelo Akka란 메시지를 전송하여 그 결과값을 출력하는 예제입니다.
보낼수 있는 명령 Type
- Ask : 결과값을 기대할때 사용합니다. 비동기로 수신하며, 동기처리시 .Result를 붙입니다. ( C#의 Async 프로그래밍 )
- Tell : 결과값이 필요 없을때 , 단지 전송만 하고 대기처리가 없습니다. 로직상 Tell에의해 어떠한 뒤늦은 결과값을 예상할수도 있습니다.
Child 액터 생성과 액터선택
...
자식 노드 생성
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
Receive<string>(message => {
if (message == "createChild")
{
Context.ActorOf<MyActor>("myChild");
Sender.Tell("Create Child Succed:myChild");
}
else
{
Sender.Tell("RE:" + message);
}
}); |
문자열 수신부분을 수정을 하여, createChild 란 문자열을 받을시 'myChild' 란 하위 노드의 액터를 생성하고
자식액터(하위노드) 의 생성을 반환하는 메시지를 응답하는 예제입니다.
이것을 작동시키는 코드는 아래와 같이 하면 되겠습니다.
특정노드를 선택하여, 자식 노드 동적으로만들고, 자식노드에게 메시지 보내기
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
protected void SomeTest2()
{
IActorRef myActor = actorSystem.ActorOf<MyActor>("myactor");
Console.WriteLine(myActor.Ask("createChild").Result);
Console.WriteLine(actorSystem.ActorSelection("/user/myactor").Ask("Hello Akka1").Result);
Console.WriteLine( actorSystem.ActorSelection("/user/myactor/myChild").Ask("Hello Akka2").Result );
} |
Expand | ||
---|---|---|
| ||
Create Child Succed:myChild |
주로 어떠한 메시지를 받았을때, 동적으로 액터를 생성시 활용을 합니다. REST API의 Endpoint체계는 다소 정적이지만
Actor의 EndPoint체계는 이러한 이유로 , 뎁스 추가 삭제가 자유롭습니다.
사용자가 만든 액터 루트의 최상위는 'user' 이며 만든 계층에따라 하위 뎁스로 가거나 수평으로 뻗어 가게 됩니다.
actorSystem에 의해 어떠한 이름(myactor))으로 만들어졌다면 'user/myactor'
myactor가 어떠한 이름(myChild) 하위 노드를 만들었다면 'user/myactor/myChild' 이렇게 계층화가 됩니다.
그리고 , 액터시스템은 어떠한 액터라도 선택할수 있으며
actorSystem.ActorSelection( 액터주소).어떠한액션() 이러한 접근방식으로 메시지 전송이 가능합니다.
액터 생성 Factory화
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
public class DemoActor : ReceiveActor
{
private readonly int _magicNumber;
public DemoActor(int magicNumber)
{
_magicNumber = magicNumber;
Receive<int>(x =>
{
Sender.Tell(x + _magicNumber);
});
}
public static Props Props(int magicNumber)
{
return Akka.Actor.Props.Create(() => new DemoActor(magicNumber));
}
}
system.ActorOf(DemoActor.Props(42), "demo"); |
자신의 액터 생성방식을 자신의 클래스내에서 정의하고 외부에 제공해주는것은 휼륭한 아이디어 입니다.
Info |
---|
Props Actor생성을 위해 옵션을 지정하고, 이를 통해 액터 생성방법을 공유하기위한 구성클래스입니다. 몇가지 Props를 통한 다양한 액터 생성법
|