我正在编写一个应该监视另一个Actor
的Actor
;让我们将后者称为目标。一旦目标停止,我的Actor
就应该停止。对于这个目标,我只有一个ActorSelection
。为了观看它,我显然需要一个ActorRef
,所以我想我应该向ActorSelection
发送一个Identify
消息;当它用ActorIdentity
回复时,我将得到它的ActorRef
。到目前为止还不错,但我无法让它开始工作。
这是规范:
// Arrange
val probe = TestProbe()
val target = TestProbe().ref
val sut = system.actorOf(MyActor.props(system.actorSelection(target.path)), "watch-target")
probe watch sut
// Act
target ! PoisonPill
// Assert
probe.expectTerminated(sut)
以及实现( FSM
,details跳过):
log.debug("Asking target selection {} to identify itself; messageId={}", selection.toString(), messageId)
selection ! Identify(messageId)
when(Waiting) {
case Event(ActorIdentity(`messageId`, Some(ref)), Queue(q)) =>
log.info("Received identity for remote target: {}", ref)
context.watch(ref)
goto(NextState) using TargetFound(ref)
case Event(ActorIdentity(`messageId`, None), Queue(q)) =>
log.error("Could not find requested target {}", selection.toString())
stop()
}
initialize()
现在,当我运行我的测试时,它是绿色的,因为被测试的系统确实被停止了。但问题是,它停止了自己,因为它无法找到它的目标使用上述步骤。日志文件说:
请求目标选择ActorSelectionAnchor(akka://default/)、路径(/system/testProbe-3)来标识自己;messageId=871823258 无法找到请求的目标ActorSelectionAnchor(akka://default/)、路径(/system/testProbe-3)
我是不是漏掉了什么明显的东西?也许TestProbe
不应该透露它的真实身份?我甚至尝试将虚拟Actor
实例化为目标,但结果是一样的。有线索吗?
发布于 2016-03-05 19:12:17
结果,答案其实很简单:测试运行得如此之快,以至于在MyActor
将Identify
消息发送到selection
之前,所选内容背后的Actor
已经收到了它的PoisonPill
,因此被杀死了。
在发送之前添加一点Thread.sleep()
,PoisonPill
修复了这个问题。
发布于 2016-03-05 19:15:39
在发出标识请求之前,目标参与者将被终止。这是因为Akka只保证在给定的一对参与者之间发送消息时的顺序。。
如果在下面的行前面添加了一个thread.sleep
,则标识请求将成功。
Thread.sleep(100)
// Act
target ! PoisonPill
注意,可能有更好的方法来编写测试--休眠线程并不理想。
您的监视参与者还应该处理目标参与者的Terminated
消息,正如这里所描述的那样。
https://stackoverflow.com/questions/35818260
复制相似问题