2016-03-05 2 views
0

Я пишу 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, деталь пропущена):

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 (Акка: // по умолчанию /), путь (/ система/testProbe-3)]

Я пропускаю что-то очевидное здесь? Может быть, TestProbe не должен раскрывать свою настоящую личность? Я даже попытался создать экземпляр манекена Actor как target, но результаты одинаковы. Любая подсказка?

ответ

0

Оказывается, ответ на самом деле очень прост: тест проходит так быстро, что перед MyActor посылает Identify сообщения selection, то Actor за отбором уже получило свой PoisonPill и, таким образом, погибают.

Добавив немного Thread.sleep() перед отправкой этого PoisonPill исправил проблему.

0

Целевой актив прекращается до того, как делается запрос идентификации. Это потому, что Akka only guarantees order when sending messages between a given pair of actors.

Если вы добавите thread.sleep выше следующей строки, запрос идентификации должен быть успешным.

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

Обратите внимание, что могут быть лучшие способы кодирования теста - спящий поток не идеален.

Ваш наблюдающий актер должен также обрабатывать сообщение Terminated целевого актера, как описано here.