관리 메뉴

HAMA 블로그

예제로 보는 아카(akka) - 10. Inbox 본문

Akka

예제로 보는 아카(akka) - 10. Inbox

[하마] 이승현 (wowlsh93@gmail.com) 2016. 10. 10. 10:08

- Scala 2.11 기반 

- Akka 2.4.11 기반 

- Akka 공식문서 참고  


InBox

이전에 액터끼리의 통신하는 방법으로 (메세지를 전달하는 방법으로)  tell (!)  과 ask (?) 를 배웠던 기억이 있을 것이다. tell 은 전형적인 보내고 잊기 방식이고 ask 는 비동기적으로 회신을 받을 수 있는 방식이었다. 그럼 InBox 는 무엇이냐면 또 다른 메세지를 전달 하는 방식인데, 임의의 액터를 하나 만들어서 이 놈이 대신 보내고 받는것이다. 중요한 포인트는 동기적으로 회신을 받는다는 점이다. 즉 타임아웃 시간동안은 멈춘다는것이며  따라서 절대로 receive 핸들러 안에서 사용하면 안된다. 이러한 성질을 이용하여 여러 액터들로 부터  다중 회신을 받거나 주로 watch 메소드 이용하여  다른 액터들을 감시하기 위해 사용된다.

다음 예를 보자. 

import akka.actor.{ ActorRef, ActorSystem, Props, Actor, Inbox }
import scala.concurrent.duration._

case object Greet
case class WhoToGreet(who: String)
case class Greeting(message: String)

class Greeter extends Actor {
  var greeting = ""

  def receive = {
    case WhoToGreet(who) => greeting = s"hello, $who"
    case Greet           => sender ! Greeting(greeting) // Send the current greeting back to the sender
  }
}

object HelloAkkaScala extends App {

  val system = ActorSystem("helloakka")

  val greeter = system.actorOf(Props[Greeter], "greeter")

  val inbox = Inbox.create(system)

  greeter.tell(WhoToGreet("akka"), ActorRef.noSender)

  inbox.send(greeter, Greet)
  val Greeting(message1) = inbox.receive(5.seconds)
  println(s"Greeting: $message1")

  val greetPrinter = system.actorOf(Props[GreetPrinter])
  system.scheduler.schedule(0.seconds, 1.second, greeter, Greet)(system.dispatcher, greetPrinter)

}

class GreetPrinter extends Actor {
  def receive = {
    case Greeting(message) => println(message)
  }
}


  val inbox = Inbox.create(system)

임의로 액터를 하나 만들었다.

  inbox.send(greeter, Greet)

greeter 액터에게 Greet 메세지를 보낸다.  (tell 이나 ask 가 아니라 send 이다) 

 val Greeting(message2) = inbox.receive(5.seconds)

타임아웃을 5초로 설정하고 수신을 받는다.


공식문서 

The Inbox

액터들과 통신하려고 할때  ask 패턴을 사용할 수 도 있을 것이다.  근데 ask 로 할 수 없는 2가지가 있는데 다중회신을 받는것과 (ActorRef 를 알려주어) 다른 액터의 라이프싸이클을 감시하는것이다.  

  1. final Inbox inbox = Inbox.create(system);
  2. inbox.send(target, "hello");
  3. try {
  4. assert inbox.receive(Duration.create(1, TimeUnit.SECONDS)).equals("world");
  5. } catch (java.util.concurrent.TimeoutException e) {
  6. // timeout
  7. }

watch 메소드를 이용하여 다른 액터를 감시하는 감시하다가 그 액터가 종료되면 메세지를 수신한다. 

  1. final Inbox inbox = Inbox.create(system);
  2. inbox.watch(target);
  3. target.tell(PoisonPill.getInstance(), ActorRef.noSender());
  4. try {
  5. assert inbox.receive(Duration.create(1, TimeUnit.SECONDS)) instanceof Terminated;
  6. } catch (java.util.concurrent.TimeoutException e) {
  7. // timeout
  8. }




Comments