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)
}
}
我有一个基于 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)
}
}