Akka: Как запланировать повторы неудачи с растущими интервалами задержки?

Каков хороший способ заставить актера попробовать что-то снова при неудаче, но с растущими интервалами времени между попытками? Скажем, я хочу, чтобы актер попытался снова через 15 секунд, затем 30 секунд, затем каждую минуту в течение ограниченного количества раз.

Вот что я придумал:

  • метод актера, который выполняет фактическую работу, имеет необязательный RetryInfo, который, если присутствует, содержит номер повторимся, мы в настоящее время находимся в
  • при сбое, актер отправит себе новый ScheduleRetryMessage с retryCount + 1, а затем выбросит исключение RuntimeException
  • другой актер контролирует действующего актера, используя new OneForOneStrategy(-1, Duration.Inf(), возвращая Resume в качестве своей Директивы. Актер не имеет состояния, поэтому Resume должно быть ОК
  • при приеме ScheduleRetryMessage, актер будет
    • if retryCount < MAX_RETRIES: используйте планировщик Akka, чтобы запланировать отправку RetryMessage после желаемой задержки
    • else: наконец-то сдаться, отправить сообщение другому игроку для сообщения об ошибках

Это хорошее решение или есть лучший подход?

Ответ 1

У вас может быть супервизор, который запускает действующего актера. Совет из документов - объявить маршрутизатору размера один для рабочего. Наблюдатель будет отслеживать количество повторных попыток, а затем планировать отправку сообщения работнику по мере необходимости.

Даже если вы создадите еще один слой актеров, это кажется мне более чистым, так как вы будете держать надзорную функциональность вне рабочего. В идеале вы могли бы сделать это 1 супервизором для русских рабочих, но я думаю, вам придется использовать Lifecycle Monitoring, чтобы получить отказ от дочернего актера. В этом случае вы можете просто сохранить карту [ActorRef, Int], чтобы отслеживать количество попыток для всех контролируемых работников. Политика надзора будет возобновлена, но если вы достигнете своих максимальных попыток, вы можете отправить PoisonPill нарушителю ActorRef.

Ответ 2

В таких случаях я использую стандартный надзор. Родительский/контролирующий субъект определяет повторы в окне времени. Повторяющийся рабочий ребенок просто перенаправляет сообщение, которое вызвало сбой с задержкой в ​​preRestart().

Если повторный ребенок довольно сложный, вы можете рассмотреть возможность соединения промежуточного актера. Этот актер просто усиливает надзор. На preRestart промежуточный актер рассылает сообщение с задержкой (restart). Поскольку промежуточный актер сохранил свое состояние, он может просто перезапустить рабочий актер (с задержкой).

Как вы можете видеть, отсроченная часть может быть в preRestart или при запуске рабочего.