-
AKKA 샘플 예제 분석하기 - akka QUICKSTART javaJava/Akka 2021. 5. 21. 16:35
Akka 솔직히 좀 개념이 좀 생소해서 어떨때에 어떻게 사용해야하는지 분간이 안가서 학습중이다.
Akka 정의
Akka는 오픈 소스 툴킷으로, JVM 상의 동시성과 분산 애플리케이션을 단순화하는 런타임이다.
pom.xml
<dependency> <groupId>com.typesafe.akka</groupId> <artifactId>akka-actor-typed_2.13</artifactId> <version>2.6.14</version> </dependency> <dependency> <groupId>com.typesafe.akka</groupId> <artifactId>akka-actor-testkit-typed_2.13</artifactId> <version>2.6.14</version> <scope>test</scope> </dependency>
AKKA 프로젝트 템플릿 다운로드
http://dev.lightbend.com/start/?group=akka&project=akka-quickstart-java
AKKA 는 자바개발환경에서는 maven, gradle 로 실행 가능하고, 스칼라 사용시 SBT 로 빌드 후 사용 가능하다.
프로젝트를 받게되면
AkkaQuickstart 라는 java 파일이 있다.
//#actor-system final ActorSystem<GreeterMain.SayHello> greeterMain = ActorSystem.create(GreeterMain.create(), "helloakka"); //#actor-system //#main-send-messages greeterMain.tell(new GreeterMain.SayHello("Charles")); //#main-send-messages
ActorSystem 을 생성하고
main 액터에 메시지를 보낸다.
GreeterMain
public class GreeterMain extends AbstractBehavior<GreeterMain.SayHello> { public static class SayHello { public final String name; public SayHello(String name) { this.name = name; } } private final ActorRef<Greeter.Greet> greeter; public static Behavior<SayHello> create() { return Behaviors.setup(GreeterMain::new); } private GreeterMain(ActorContext<SayHello> context) { super(context); //#create-actors greeter = context.spawn(Greeter.create(), "greeter"); //#create-actors } @Override public Receive<SayHello> createReceive() { return newReceiveBuilder().onMessage(SayHello.class, this::onSayHello).build(); } // 3개의 GreetoerBot 을 생성 후 Greeter 에게 메시지와 누구에게 메시지를 보낼지 대상을 전달한다. private Behavior<SayHello> onSayHello(SayHello command) { //#create-actors ActorRef<Greeter.Greeted> replyTo = getContext().spawn(GreeterBot.create(3), command.name); greeter.tell(new Greeter.Greet(command.name, replyTo)); //#create-actors return this; } }
AbstractBehavior 클래스를 상속받은 GreeterMain 에게 Charles 라는 메시지를 보내면
AbstractBehavior 클래스의 createReceive 메소드에서 receive 받기로 한 메소드가 실행이 된다.
createReceive 에는 메시지 받는 타입과 메시지 받은 이후의 처리를 담당하는 handler 를 설정할 수 있다.
예제에서는 handler 가 onSayHello 메소드 이다.
onSayHello 의 메소드는 응답받을 3개의 GreeterBot 을 만든다.
그 후
ActorRef<Greeter.Greet> greeter;
ActorRef 변수 greeter 에게 메시지와 메시지를 보낼 대상일 GreeterBot(ActorRef) 객체를 보낸다.
Greeter.class
public class Greeter extends AbstractBehavior<Greeter.Greet> { public static final class Greet { public final String whom; public final ActorRef<Greeted> replyTo; public Greet(String whom, ActorRef<Greeted> replyTo) { this.whom = whom; this.replyTo = replyTo; } } public static final class Greeted { public final String whom; public final ActorRef<Greet> from; public Greeted(String whom, ActorRef<Greet> from) { this.whom = whom; this.from = from; } public static Behavior<Greet> create() { return Behaviors.setup(Greeter::new); } private Greeter(ActorContext<Greet> context) { super(context); } @Override public Receive<Greet> createReceive() { return newReceiveBuilder().onMessage(Greet.class, this::onGreet).build(); } // GreeterMain actorRef 가 tell 할 경우 실행된다. private Behavior<Greet> onGreet(Greet command) { getContext().getLog().info("Hello {}!", command.whom); //#greeter-send-message command.replyTo.tell(new Greeted(command.whom, getContext().getSelf())); //#greeter-send-message return this; } }
여기서 또 AbstractBehavior 클래스를 상속받은 Greeter 가
createReceive 에서 연결된 Greet 타입으로 onGreet 메소드를 실행한다.
이번 onGreet 메소드에는 특이하게 GreeterMain 의 onSayHello 에서 보낸 GreeterBot(ActorRef) 가 있어서
GreeterBot 이 tell 하도록 한다.
GreeterBot.class
public class GreeterBot extends AbstractBehavior<Greeter.Greeted> { public static Behavior<Greeter.Greeted> create(int max) { return Behaviors.setup(context -> new GreeterBot(context, max)); } private final int max; private int greetingCounter; private GreeterBot(ActorContext<Greeter.Greeted> context, int max) { super(context); this.max = max; } @Override public Receive<Greeter.Greeted> createReceive() { return newReceiveBuilder().onMessage(Greeter.Greeted.class, this::onGreeted).build(); } // Greeter actorRef 가 onGreet 할때 tell 시킨다. private Behavior<Greeter.Greeted> onGreeted(Greeter.Greeted message) { greetingCounter++; getContext().getLog().info("Greeting {} for {}", greetingCounter, message.whom); if (greetingCounter == max) { return Behaviors.stopped(); } else { message.from.tell(new Greeter.Greet(message.whom, getContext().getSelf())); return this; } } }
코드 요약
GreeterMain 에게 tell 을 한 후 Main 에 생성 되어 있는 ActorRef(greeter) 에게 tell 을 하고, 응답을 ActoerRef(greeterBot) 이 응답한다.
실행
akka 자바 공식문서
반응형