简体   繁体   English

使用ActorSelection识别演员

[英]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. 事实证明答案实际上非常简单:测试运行如此之快, MyActorIdentify消息发送给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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM