0

私はActor別のものを見なければならない を書いていActorます。後者をtargetと呼びましょう。Actorターゲットが停止すると、自分自身を停止する必要があります。このターゲットには、ActorSelection. それを見るには、明らかに が必要なので、メッセージActorRefを送信する必要があると考えました。それが返信すると、私はその. ここまでは順調ですが、うまくいきません。ActorSelectionIdentifyActorIdentityActorRef

仕様は次のとおりです。

// 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詳細は省略):

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()

テストを実行すると、テスト中のシステムが実際に停止しているため、緑色になります。しかし、問題は、前述の手順を使用してターゲットを見つけることができないため、停止することです。ログファイルには次のように記載されています。

ターゲットの選択 ActorSelection[Anchor(akka://default/), Path(/system/testProbe-3)] にそれ自体を識別するように依頼します。messageId=871823258

要求されたターゲット ActorSelection [Anchor(akka://default/), Path(/system/testProbe-3)] が見つかりませんでした

ここで明らかな何かが欠けていますか?多分 aTestProbeはその正体を明かすべきではありませんか? ダミーActorターゲットとしてインスタンス化してみましたが、結果は同じです。どんな手掛かり?

4

2 に答える 2

0

答えは実際には非常に単純であることがわかります。テストは非常に高速に実行されるため、 にメッセージをMyActor送信する前に、選択の背後にある が既にメッセージを受信して​​いるため、強制終了されます。IdentifyselectionActorPoisonPill

Thread.sleep()送信する前に少し追加するとPoisonPill、問題が修正されました。

于 2016-03-05T19:12:17.057 に答える
0

識別要求が行われる前に、ターゲット アクターが終了しています。これは、特定のアクターのペア間でメッセージを送信するときに、Akka が順序のみを保証するためです。

次の行の上に a を追加するthread.sleepと、識別要求が成功するはずです。

Thread.sleep(100)
// Act
target ! PoisonPill

テストをコーディングするより良い方法があるかもしれないことに注意してください - スレッドをスリープ状態にすることは理想的ではありません。

ここで説明されているように、ウォッチング アクターはTerminatedターゲット アクターのメッセージも処理する必要があります。

于 2016-03-05T19:15:39.997 に答える