演员为什么要开始两次?

时间:2019-07-03 20:29:00

标签: scala akka akka-typed

我只启动一次儿童演员,如下所示:

object DetectorSupervisor {

  def create(): Behavior[NotUsed] =
    Behaviors.setup { context =>

      context.log.info(s"=============> Start DetectorSupervisor <=============")

      val informant = context.spawn(InformantActor.create(Vector.empty), "InformantActor")
      val stateMachine = context.spawn(DetectorStateMachine.create(informant,
        State(KafkaInactiveConfirmed, SapInactiveConfirmed)), "StateMachine")

      context.spawn(DetectorReceptionActor.create(informant), "ReceptionActor")

      context.spawn(KafkaDetectorActor.create(stateMachine, None), "KafkaActor")
      context.spawn(SapDetectorActor.create(stateMachine, None), "SapActor")

      Behavior.empty

    }

} 

在日志中,我可以看到一个演员总是开始两次。

[INFO] [07/03/2019 22:21:35.513] [testSystem1-akka.actor.default-dispatcher-2] [akka://testSystem1/user/DetectorSupervisor] =============> Start DetectorSupervisor <=============
[INFO] [07/03/2019 22:21:37.456] [testSystem1-akka.actor.default-dispatcher-3] [akka://testSystem1/user/DetectorSupervisor/InformantActor] =============> Start InformantActor <=============
[INFO] [07/03/2019 22:21:37.460] [testSystem1-akka.actor.default-dispatcher-3] [akka://testSystem1/user/DetectorSupervisor/StateMachine] =============> Start DetectorStateMachine <=============
[INFO] [07/03/2019 22:21:37.460] [testSystem1-akka.actor.default-dispatcher-3] [akka://testSystem1/user/DetectorSupervisor/ReceptionActor] =============> Start DetectorReceptionActor <=============
[INFO] [07/03/2019 22:21:37.473] [testSystem1-akka.actor.default-dispatcher-4] [akka://testSystem1/user/DetectorSupervisor/SapActor] =============> Start SapDetectorActor <=============
[INFO] [07/03/2019 22:21:37.473] [testSystem1-akka.actor.default-dispatcher-5] [akka://testSystem1/user/DetectorSupervisor/KafkaActor] =============> Start KafkaDetectorActor <=============
[INFO] [07/03/2019 22:21:37.503] [testSystem1-akka.actor.default-dispatcher-5] [testSystem1] =============> Start KafkaDetectorStream <=============
[INFO] [07/03/2019 22:21:37.503] [testSystem1-akka.actor.default-dispatcher-4] [testSystem1] =============> Start SapDetectorStream <=============
[INFO] [07/03/2019 22:21:43.950] [testSystem1-akka.actor.default-dispatcher-3] [akka://testSystem1/user/DetectorSupervisor/InformantActor] =============> Start InformantActor <============= 

如您所见,InformantActor开始两次,我不知道为什么。

这是InformantActor的实现:

object InformantActor {

  sealed trait InformantEvent

  case object ServerOnlineConfirmed extends InformantEvent

  case object ServerOfflineConfirmed extends InformantEvent

  case class SubscribersChanged(actor: Vector[ActorRef[ServerEvent]]) extends InformantEvent


  def create(subscribers: Vector[ActorRef[ServerEvent]]): Behavior[InformantEvent] =
    Behaviors.setup { context =>

      context.log.info(s"=============> Start InformantActor <=============")

      Behaviors.receiveMessage[InformantEvent] {
        case ServerOfflineConfirmed =>
          subscribers.foreach(a => a ! ServerOfflineApproved)
          Behavior.same
        case ServerOnlineConfirmed =>
          subscribers.foreach(a => a ! ServerOnlineApproved)
          Behavior.same
        case SubscribersChanged(actors) =>
          create(actors)
      }
    }

}

源代码托管在https://gitlab.com/sweetsoft/plugger上。

1 个答案:

答案 0 :(得分:2)

我不认为它启动了两次。

您的create函数是递归的,并在case SubscribersChanged(actors) =>发生时执行。

因此,每当订户列表更改时,您都会看到日志消息。

您重构create以便从递归中排除日志消息……类似这样:

def create(initialSubscribers: Vector[ActorRef[ServerEvent]]): Behavior[InformantEvent] = {
  Behaviors.setup { context =>

    context.log.info(s"=============> Start InformantActor <=============")

    def behavior(subscribers: Vector[ActorRef[ServerEvent]]): Behavior[InformantEvent] = Behaviors.receiveMessage[InformantEvent] {
      case ServerOfflineConfirmed =>
        subscribers.foreach(a => a ! ServerOfflineApproved)
        Behavior.same
      case ServerOnlineConfirmed =>
        subscribers.foreach(a => a ! ServerOnlineApproved)
        Behavior.same
      case SubscribersChanged(actors) =>
        behavior(actors)
    }

    behavior(initialSubscribers)
  }
}