停止一个Actor实例并等待它停止

时间:2017-06-16 09:51:14

标签: akka

我的Actor中有以下代码(我称之为Actor MasterActor)接收方法:

  override def receive: Receive = {
    case StopActor(id, actorConfig) =>
      log.info(s"Stopping actor with id = $id and config $actorConfig")

      stopActor(id, powerPlantCfg).pipeTo(self)
      context.become(waitForStop(sender()))

    // Other messages... not shown here for simplicity
  }

所以我上面要做的就是停止actor并将Future的结果[Continue](其中Continue是Monix Ack类型)传递给包含上述Receive方法的Actor。 stopActor看起来像这样:

  private def stopActor(id: Long, cfg: ActorConfig): Future[Ack] = async {
    await(fetchActor(id).materialize) match {
      case scala.util.Success(actorRef) =>
        log.info(s"Stopping Actor with id = $id")
        context.watch(actorRef)
        context.stop(actorRef)
        Continue
      case scala.util.Failure(fail) =>
        log.error(s"Could not fetch Actor instance for id = $id because of: $fail")
        Continue
    }
  }

我正在做context.watch(actorRef),这就是我的waitForStop的样子:

  private def waitForStop(source: ActorRef): Receive = {
    case Continue =>
      source ! Continue
      context.become(receive)

    case someShit =>
      log.error(s"Unexpected message $someShit received while waiting for an actor to be stopped")
  }

所以我在这里有两个问题:

  1. 在执行context.become(waitForStop(sender()))时,我正在关闭sender(),所以我假设在这种情况下发送者是包含以上所有代码的ActorRef, MasterActor。我是对的吗?

  2. 我如何明确知道我试图停止的这个ActorRef实际上已停止,以便我可以在它停止后立即执行context.unwatch(actorRef)?

  3. 有什么建议吗?

1 个答案:

答案 0 :(得分:2)

通过观看,可以通知您演员的停止。您已熟悉手表:

val kenny = context.actorOf(Props[Kenny], name = "Kenny")
context.watch(kenny)

然后您可以等待已终止的消息。一旦收到,你就可以看到你需要的东西了。

def receive = {
    case Terminated(kenny) => println("OMG, they killed Kenny")
    case _ => println("Parent received a message")
}

所以我的推荐是简单地观察,等待终止,并发出停止命令。但是我不确定你究竟在问什么,所以这可能是错误的 Blog post example