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 или при запуске рабочего.