如何在 Scala 中使用 Akka 实现 parent-children 模型?

How to implement parent-children model with Akka in Scala?

我想用 Scala 和 Akka 实现一个小的 HTTP 服务器。具体来说,我想要两种演员:EmployeeRouterActor 和 EmployeeEchoActor。

第一个,我想像路由器一样使用它,我的意思是,actor 接收所有消息并且它必须为每条消息创建一个 child(在本例中为 EmployeeEchoActor)。

每个child,它都会收到一条Employee消息,它必须返回一个包含员工信息的字符串。

此外,在child完成它的过程后,child必须死掉。我认为 parent 是谁必须控制他们 children 的生命周期。

在 Akka 文档中,我只看到关于使用单个 child,例如 this

我该怎么做? Akka 站点是否有任何示例或任何其他文档?

像这样:

object EmployeeRouterActor {
  final case class Employee(id: String, name: String)
  final case object StopChild
  final case class ChildResponse(id: String, data: String)
}

final class EmployeeRouterActor extends Actor {
  import EmployeeRouterActor._

  // Make a map which will store child actors
  private var children = Map.empty[String, ActorRef]

  override def receive: Receive = {
    case e @ Employee(id, _)  => getChild(id) ! e
    case ChildResponse(id, _) => stopChild(id)
  }

  // Check whether child exists in context of this actor.
  // If it doesn't, create new one.
  private def getChild(id: String): ActorRef =
    context.child(id).getOrElse {
      val child = context.actorOf(EmployeeEchoActor.apply(), id)
      children += (id -> child)
      child
    }

  private def stopChild(id: String) = {
    children(id) ! StopChild
    children -= id
  }
}

object EmployeeEchoActor {
  def apply(): Props = Props(new EmployeeEchoActor)
}

final class EmployeeEchoActor extends Actor {
  // self.path.name to access its id
  override def receive: Receive = {
    case EmployeeRouterActor.Employee =>
      // do stuff with Employee message...
      context.parent ! EmployeeRouterActor.ChildResponse(self.path.name, "Done!") // Or pipeTo(context.parent)
    case EmployeeRouterActor.StopChild => context.stop(self)
  }
}

基本上,child 个演员被创建并存储在 Map 中。当他们完成任务时,他们会回复 parent 的响应消息,然后停止他们。