Akka OneForOneStrategy не работает

У меня есть следующий код:

class A extends Actor with ActorLogging {
  override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 2) { 
    case _ => log.info("An actor has been killed"); Restart 
  }

  val b = context.system.actorOf(Props[B], "b")

  def receive = {
    case _ => context.system.scheduler.schedule(5 seconds, 5 seconds, b, true)
  }
}

class B extends Actor with ActorLogging {
  def receive = { case true => self ! Kill }
}

После self ! Kill в экземпляре актера A я не вижу сообщения "Актер был убит", а последующий вызов актера A генерирует сообщение "мертвые буквы", поэтому перезапуска не было. Почему OneForOneStrategy не звонят?

Странно, что я могу просто удалить все переопределение OneForOneStrategy, и никаких изменений в поведении программы не произойдет.


person src091    schedule 27.03.2014    source источник


Ответы (2)


val b = context.system.actorOf(Props[B], "b") следует изменить на val b = context.actorOf(Props[B], "b"), чтобы новый актор был дочерним, а не актором верхнего уровня.

person src091    schedule 27.03.2014

Вы одновременно перезапускаете актор «B», а затем выдаете исключение при его перезапуске. Удалите self ! true из кода postRestart. В противном случае, чего вы ожидаете? Вы отправляете его в бесконечно рекурсивный цикл перезапуска.

Вот порядок или действия, которые вы видите, чтобы проиллюстрировать это:

  1. Создать актера "А"
  2. Создать актера "Б"
  3. отправить true в А
  4. отправить true в B
  5. "B" выдает исключение в сообщении true
  6. «А» перезапускает «Б»
  7. после перезапуска "B" отправляет себе true
  8. повторить шаг 5
person wheaties    schedule 27.03.2014
comment
Хорошо, но что тогда должен делать maxNrOfRetries = 2? Я, конечно, знаю о бесконечном цикле, но я думал, что он должен быть прекращен после двух попыток родительским актером A из-за этой самой опции. - person src091; 27.03.2014
comment
@Anton Хорошо, если был вызван postRestart, это означает, что Актер был успешно перезапущен. Таким образом, количество попыток было равно 1. - person wheaties; 27.03.2014
comment
Я все еще не понимаю. Как я вижу, это должно работать так: пуск -> сбой -> перезагрузка №1 -> сбой -> перезагрузка № 2 -> сбой -> остановка, потому что maxNrOfRetries = 2. Я что-то упускаю? - person src091; 27.03.2014
comment
@Anton Максимальное количество попыток — это максимальное количество попыток перезапуска Актера, которое сбрасывается после успешного перезапуска. Это не максимальное количество перезапусков Актера. - person wheaties; 27.03.2014
comment
Хорошо, спасибо. Я упростил свой код и удалил рекурсию, поскольку она не имеет отношения к сути моего вопроса. - person src091; 27.03.2014