[英]Identifying an Actor using an ActorSelection
I'm writing an Actor
that should watch another Actor
; 我写的
Actor
应该看另一个Actor
; let's call the latter one the target . 让我们将后一个称为目标 。 My
Actor
should stop itself once its target is stopped. 目标停止后,我的
Actor
应该自行停止。 For this target I only have an ActorSelection
. 对于这个目标,我只有一个
ActorSelection
。 To watch it, I obviously need an ActorRef
, so I figured I should send the ActorSelection
an Identify
message; 要观看它,我显然需要一个
ActorRef
,因此我认为应该向ActorSelection
发送一个Identify
消息; when it replies back with ActorIdentity
I would have its ActorRef
. 当它用
ActorIdentity
回复时,我将得到它的ActorRef
。 So far so good, but I can't get it to work. 到目前为止还不错,但是我无法使它正常工作。
Here's the spec: 规格如下:
// 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)
And the implementation (an FSM
, details skipped): 和实现(一个
FSM
,跳过了细节):
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()
Now, when I run my test, it is green because the system under test is indeed stopped. 现在,当我运行测试时,它是绿色的,因为被测系统确实已停止。 But the problem is it stops itself because it can't find its target using the aforementioned steps.
但是问题在于它会自行停止,因为使用上述步骤无法找到目标。 The log file says:
日志文件显示:
Asking target selection ActorSelection[Anchor(akka://default/), Path(/system/testProbe-3)] to identify itself;
要求目标选择ActorSelection [Anchor(akka:// default /),Path(/ system / testProbe-3)]进行自我标识; messageId=871823258
messageId = 871823258
Could not find requested target ActorSelection[Anchor(akka://default/), Path(/system/testProbe-3)]
找不到请求的目标ActorSelection [Anchor(akka:// default /),Path(/ system / testProbe-3)]
Am I missing something obvious here? 我在这里错过明显的东西吗? Maybe a
TestProbe
should not reveal its real identity? 也许
TestProbe
不应该透露其真实身份? I even tried by instantiating a dummy Actor
as target but the results are the same. 我什至尝试通过将虚拟
Actor
实例化为目标来进行尝试,但是结果是相同的。 Any clue? 有什么线索吗?
Turns out the answer is actually very simple: the test runs so fast that before MyActor
sends the Identify
message to the selection
, the Actor
behind the selection has already received its PoisonPill
and thus is killed. 事实证明答案实际上非常简单:测试运行如此之快,
MyActor
将Identify
消息发送给selection
,选择背后的Actor
已经收到了PoisonPill
,因此被杀死。
Adding a little Thread.sleep()
before sending that PoisonPill
fixed the issue. 在发送该
PoisonPill
之前添加一点Thread.sleep()
PoisonPill
该问题。
The target actor is getting terminated before the identify request is being made. 在做出识别请求之前,目标参与者将被终止。 This is because Akka only guarantees order when sending messages between a given pair of actors .
这是因为Akka仅在给定的一对Actor之间发送消息时才保证顺序 。
If you add a thread.sleep
above the following line, the identify request should succeed. 如果在以下行上方添加
thread.sleep
,则标识请求应会成功。
Thread.sleep(100)
// Act
target ! PoisonPill
Note that there may be better ways to code the test - sleeping the thread is not ideal. 请注意,可能会有更好的方法来编写测试代码-使线程休眠并不理想。
Your watching actor should also handle the Terminated
message of the target actor, as described here . 您观看演员也应该处理
Terminated
目标的演员的消息,描述在这里 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.