Page History
Info |
---|
다음과 같은 간단한 액트를 설계해보자
- 인사를 받아주는 액트(Greeter)
- 인사에 반응하여 로그를 찍는 액트( Printer)
가장 기본적인 Actor의 설계방법을 살펴보겠습니다. Actor에 대한 사용패턴/컨셉은 언어/플래폼이 틀려도 큰 차이가 없습니다. |
액터메시지의 특징
액터는 각각 고유의 메시지 큐를 가지고 있고, 하나의 액터는 메지큐에 순차적으로
끄집어 처리하기때문에 일반적인 상황에서 순서보장이 됩니다.
더 자세한 참고자료: Actor
주요 액터 모듈
import akka.actor.ActorSystem
No Format |
---|
ActorSystem system = ActorSystem.create("helloakka"); |
어플리케이션 하나당, 일반적으로 액터 시스템도 하나이며
액터생성과 제어에 관련한 여러가지 함수를 제공합니다.
import akka.actor.AbstractActor
...
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
public class MyActor | ||||||
Code Block | ||||||
| ||||||
package com.psmon.akka.study; import com.psmon.akka.study.Printer.Greeting; import akka.actor.AbstractActor; import akka.actor.ActorRef; import akka.actor.Props; //#greeter-messages public class Greeter extends AbstractActor { //#greeter-messages staticprivate publicfinal PropsLoggingAdapter props(String message, ActorRef printerActor) { return Props.create(Greeter.class, () -> new Greeter(message, printerActor)); } //#greeter-messages static public class WhoToGreet { public final String who; public WhoToGreet(String who) { this.who = who; } } static public class Greet { public Greet() { } } //#greeter-messages private final String message; private final ActorRef printerActor; private String greeting = ""; public Greeter(String message, ActorRef printerActor) { this.message = message; this.printerActor = printerActor; } log = Logging.getLogger(getContext().getSystem(), this); @Override public Receive createReceive() { return receiveBuilder() .match(WhoToGreetString.class, wtgs -> { this.greeting =log.info("Received String message: + {}", " + wtg.whos); }) .match(Greet.class, x -> { //#greeter-send-message printerActor.tell(new Greeting(greeting), getSelf()); //#greeter-send-message }matchAny(o -> log.info("received unknown message")) .build(); } //#greeter-messages } //#greeter-messages } |
액터를 설계할때 기본적으로 상속받는 준비된 추상 액터 입니다.
위코드는 AbstaractActor를 상속받아 패턴 매칭화 해서 메시지를 처리하는 고급방법입니다.
UntypedActor 를 상속받아 우리에게 익숙한 If/Switch문을 사용할수도 있습니다.
import akka.actor.UntypedActor
Code Block | ||||||
---|---|---|---|---|---|---|
| ||||||
package com.psmon.akka.study; import akka.actor.AbstractActor; import akka.actor.ActorRef; import akka.actor.Props; import akka.event.Logging; import akka.event.LoggingAdapter; //#printer-messages public class PrinterTestActor extends AbstractActorUntypedActor { //#printer-messages static public Props props() { return Props.create(Printer.class, () -> new Printer()); } //#printer-messages static public class Greeting { public final String message; public Greeting(String message) { this.message = message; private final LoggingAdapter log = Logging } } //#printer-messages private LoggingAdapter log = Logging.getLogger(getContext().getSystemsystem(), this"TestActor"); public Printer() { } @Override @Override public Receivevoid createReceiveonReceive(Object message) throws Exception { return receiveBuilder() .match(Greeting.class, greeting -> { if(message instanceof String) { //String뿐만 아니라 모든 Java객체 통신가능 log.info(greeting."Incommessage {}", message); }) .build(); } //#printer-messages } //#printer-messages | ||||||
Code Block | ||||||
| ||||||
package com.psmon.akka.study; import akka.actor.ActorRef; import akka.actor.ActorSystem; import java.io.IOException; import com.psmon.akka.study.Greeter.*; public class AkkaQuickstart sender().tell("너의 메시지에 응답을함", ActorRef.noSender()); }else { public static void main(String[] args) { final ActorSystem system = ActorSystem.create("helloakka"); try { log.info("Unhandle Message {}", message); //#create-actors } final ActorRef printerActor = system.actorOf(Printer.props(), "printerActor"); final ActorRef howdyGreeter = system.actorOf(Greeter.props("Howdy", printerActor), "howdyGreeter"); final ActorRef helloGreeter = system.actorOf(Greeter.props("Hello", printerActor), "helloGreeter"); final ActorRef goodDayGreeter = system.actorOf(Greeter.props("Good day", printerActor), "goodDayGreeter"); //#create-actors //#main-send-messages howdyGreeter.tell(new WhoToGreet("Akka"), ActorRef.noSender()); howdyGreeter.tell(new Greet(), ActorRef.noSender()); howdyGreeter.tell(new WhoToGreet("Lightbend"), ActorRef.noSender()); howdyGreeter.tell(new Greet(), ActorRef.noSender()); helloGreeter.tell(new WhoToGreet("Java"), ActorRef.noSender()); helloGreeter.tell(new Greet(), ActorRef.noSender()); goodDayGreeter.tell(new WhoToGreet("Play} } |
객체조건에 따른 분기처리를 위한 패턴매칭은 어디서 누가? 먼저 도입한지는 모르겠으나 , Java/C# 등에서도 최근버젼에서 도입되고 사용가능한 방식이며
Scala에서는 이미 초기부터 사용가능한방식입니다. 일반적으로 오픈진영을 통합해야하는 Java 진영에서 최신 모던 언어스펙적용이
느린편이나 8이후로 가속이 붙은 느낌이 듭니다. 어쨋건 위 코드는 패턴매칭이 아닌 우리에게 익숙한 케이스바이 케이스로 처리한 방식입니다.
import akka.actor.Props
...
Code Block | ||||
---|---|---|---|---|
| ||||
Props props1 = Props.create(MyActor.class);
Props props2 = Props.create(ActorWithArgs.class,
() -> new ActorWithArgs("arg")); // careful, see below
Props props3 = Props.create(ActorWithArgs.class, "arg"); |
액터 생성옵션에 대한 정보를 보관할수가 있으며 ,옵션 재사용가능하며
액터 초기화에 필요한 여러가지 초기옵션들을 관리할수가 있습니다.
import akka.actor.ActorRef
...
Code Block | ||||
---|---|---|---|---|
| ||||
ActorRef howdyGreeter = system.actorOf( props1 , "howdyGreeter"); howdyGreeter.tell(new WhoToGreet("Akka"), ActorRef.noSender()); goodDayGreeter.tell(new Greet(), ActorRef.noSender()); //#main-send-messages System.out.println(">>> Press ENTER to exit <<<"); System.in.read(); } catch (IOException ioe) { } finally { system.terminate(); } } } | ||||
Expand | ||||
| ||||
액터의 참조자이며, 참조된 액터에게 메시지를 보내고자할때 이용됩니다.
액터는 기본적으로, 공유가 금지되었기때문에 상대 멤버접근이 불가능하며
모든것은 메시지를 통해 정보를 교환해야합니다.
그래서 이야기를 해야할 또는 물음에 답할수 있는 상대를 지정하는 방법이 중요합니다.