Akka测试模拟Actor自杀(使用watch)

Akka test simulate Actor killing itself (using watch)

我有一个基于 Akka 的应用程序,它有多个参与者系统以集群形式加入。 1个actor系统是Master,其他都是Slave。有时,可能会发生 master actor 系统崩溃的情况。在这种情况下,所有从站都形成了自己的集群。在我的用例中,我想避免这种情况,并在与主站的连接丢失后立即杀死所有从站。为了实现这一点,我在 master 上添加了一个手表。这是示例代码。

class SlaveActor(input1: String, input2: String) extends Actor {
    .....
    .....
    context.actorSelection(MASTER_ACTOR_ADDRESS) ! Identify(1)
    ....

    def receive = {
        case ActorIdentity(arg1, actorRef)=>
            actorRef.foreach(context.watch(_))
        case Terminated(actorRef) =>
            self ! PoisonPill
        .......
        .......
    }

    ......
  }
}

这一切都按预期工作,但现在我想使用 Akka 测试框架测试此行为。我尝试了不同的方法,但没有用。

注意:slave actor获取master的地址作为输入参数。

describe("master slave tests") {
it("slave should kill itself as soon as master is down") {
    val dummyActor = system.actorOf(Props.empty)
    master = system.actorOf(Props(classOf[MasterActor], TestProbe().ref, dummyActor), "context-supervisor")

    slave = system.actorOf(
        Props(classOf[SlaveActor], dummyActor, s"${master.path.address.toString}${master.path.toStringWithoutAddress}"))

    val masterProbe = TestProbe()
    masterProbe.watch(master)

    val slaveProbe = TestProbe()
    slaveProbe.watch(slave)

    // NOTE: Simulating master DOWN
    master ! akka.actor.PoisonPill
    masterProbe.expectTerminated(master)

    slaveProbe.expectTerminated(slave)
}
}

Master 成功杀死自己,但不知何故 slave Terminated 事件没有被触发。有帮助吗?

我发现了问题。这是一个时间问题。在我的经理能够添加手表之前,我的主人被杀了。我添加了一个 Thread.sleep() 来等待初始化。之后我收到了所有消息,包括终止经理。

describe("master slave tests") {
   it("slave should kill itself as soon as master is down") {
   val dummyActor = system.actorOf(Props.empty)
   master = system.actorOf(Props(classOf[MasterActor], 
                     TestProbe().ref, dummyActor), "context-supervisor")

   slave = system.actorOf(
       Props(classOf[SlaveActor], dummyActor, s"${master.path.address.toString}${master.path.toStringWithoutAddress}"))

   val masterProbe = TestProbe()
   masterProbe.watch(master)

   val slaveProbe = TestProbe()
   slaveProbe.watch(slave)

   Thread.sleep(2000)
   // NOTE: Simulating master DOWN
   master ! akka.actor.PoisonPill
   masterProbe.expectTerminated(master)

   slaveProbe.expectTerminated(slave)
 }
}