[Akka] Child Actor 생성

smlee·2023년 10월 6일
0

Akka

목록 보기
28/50
post-thumbnail

Actor는 내부에서 액터를 생성할 수도 있다. 간단한 예로 다음과 같은 코드가 될 수 있다.

  object Child {
    case object Call
  }

  class Child extends Actor {

    import Child._

    override def receive: Receive =
    {
      case Call => println("the child has been called")
    }

  }


  object Parent {
    case object CreateChild
    case object Print
  }

  class Parent extends Actor {

    import Parent._
    import Child._

    override def receive: Receive = {
      case CreateChild =>
        val child = context.actorOf(Props[Child], "child")
        context.become(withChild(child))
        
      case Print =>
        println("I have no child")
    }

    private def withChild(childActor: ActorRef): Receive = {
      case Print =>
        println("I have a child")
        childActor ! Call
    }
  }

위의 코드를 작성하고 main에서 다음과 같은 메시지를 보낸다면 결과는 다음과 같다.

  parent ! Print
  parent ! CreateChild
  parent ! Print

위의 코드를 실행하면 밑과 같이 된다.

부모 액터에서 생성한 자식 액터가 제대로 생성되었으며, 자식 액터에 메시지도 제대로 보내진다는 것을 알 수 있다. 한 가지 주의해야할 점은 부모 액터 역시 자식 액터에 접근을 못하고 proxy 역할인 ActoreRef로 메시지를 보내야 한다는 점이다.

그렇다면 여러 자식 액터를 만드려면 어떻게 할까?


object Child {
    case object Call
  }

  class Child extends Actor {

    import Child._

    override def receive: Receive =
    {
      case Call => println(s"[$self.path] the child has been called")
    }

  }


object Parent {
    case class CreateChildren(nChildren:Int)
    case object Print
  }

  class Parent extends Actor {

    import Parent._
    import Child._

    override def receive: Receive = {
      case CreateChildren(nChildren: Int) =>
        val children = (0 until nChildren).map(index => context.actorOf(Props[Child], s"child$index"))
        context.become(withChildren(children))
        
      case Print =>
        println("I have no child")
    }

    private def withChildren(children: IndexedSeq[ActorRef]): Receive = {
      case Print =>
        println("I have children")
        children.foreach(child => child ! Call)
    }
  }

여러 개의 자식 액터를 명확하게 확인하기 위해 자식 액터가 호출되었을 때 self.path를 호출하도록 하였다. 위의 코드를 다음과 같은 코드로 실행하면 어떨까?

  val system = ActorSystem("system")

  val parent = system.actorOf(Props[Parent], "parent")

  parent ! Print
  parent ! CreateChildren(5)
  parent ! Print

위는 5개의 자식 액터를 생성하기 위한 코드이다. 위의 코드를 실행하면

위와 같이 되는데, child 0부터 child 4가 제대로 생성되는 것을 알 수 있다.

0개의 댓글