Сохранение и воспроизведение сообщений с перезапущенными актерами в Akka

Akka Java здесь. У меня есть два актера, Parent и Child, где первый является родителем второго. Если Child выдает конкретное исключение (скажем, UnrulyTeenagerExcepton), то поведение, которое я ищу, выглядит следующим образом:

  • Parent сохраняет ссылку на сообщение, которое обрабатывалось Child, когда возникло исключение; потом
  • Child перезапускается, и сохраненное сообщение «воспроизводится» в Child; но
  • Если этот цикл сохранения -> перезапуска -> воспроизведения происходит три раза, и Child выдает UnrulyTeenagerException три раза, тогда мы SupervisorStrategy.escalate()

Моя лучшая попытка на данный момент:

// Groovy pseudo-code
class ChildFailureDecider extends Function<Throwable,Directive> {
    int maxRetries = 3
    int numRetries = 0

    @Override
    Directive apply(Throwable childFailure) {
        if(childFailure instanceof UnrulyTeenagerException) {
            numRetries++

            if(numRetries <= maxRetries) {
                // TODO: #1 How to persist the message that caused the ‘childFailure’?

                return SupervisorStrategy.restart()

                // TODO: #2 How to ‘play back’ the persisted message to Child?
            }
        }

        SupervisorStrategy.escalate()
    }
}

Но, как видите, я борюсь с сохранением сообщений и их воспроизведением. Любые идеи? Приветствуются примеры кода Java, Akka достаточно сложна и без необходимости изучать иероглифы Scala!


person smeeb    schedule 25.08.2015    source источник
comment
С помощью «постоянно» вы требуете, чтобы сообщение записывалось на диск или просто сохранялось в том смысле, что оно фиксируется в переменной внутри родительского элемента?   -  person mattinbits    schedule 26.08.2015
comment
Спасибо @mattinbits (+1) - я догадываюсь под сохранением я имею в виду все, что достигается с помощью модуля Akka-Persistence и UntypedPersistentActorWithAtLeastOnceDelivery. Однако, по общему признанию, я не совсем понимаю, как работают персистентные акторы, и поэтому, возможно, они отличаются от варианта использования, который я здесь представляю. В конце концов, мне просто нужно, чтобы Akka сохранила (где-то) сообщение, которое не удалось обработать дочернему элементу, перезапустить дочерний элемент, а затем повторно обработать это сохраненное сообщение в перезапущенном дочернем элементе. Мысли? Спасибо еще раз!   -  person smeeb    schedule 26.08.2015


Ответы (1)


Постоянство Akka — это запись событий (не то же самое, что сообщения) в постоянном режиме (например, на диск или в базу данных) в постоянном режиме, так что, если все ваше приложение завершится (например, сбой JVM или аппаратный сбой), можно восстановить состояние этого актера при перезапуске. В вашем случае вы хотите запомнить сообщение, отправленное одному актеру, и повторно отправить его, когда этот актер перезапускается из-за сбоя, поэтому я не думаю, что в этом случае вам нужен API сохранения.

Когда действующее лицо выдает исключение, это исключение представляется супервизору, а сообщение, вызвавшее его, — нет. Я не думаю, что для этого есть встроенный способ. Супервизор может управлять правилом перезапуска только 3 раза, задав стратегию супервизии с соответствующими параметрами: http://doc.akka.io/japi/akka/2.4-M3/akka/actor/OneForOneStrategy.html#OneForOneStrategy-int-scala.concurrent.duration.Duration-akka.japi.Function-

Отправитель должен обрабатывать повторное воспроизведение сообщений. Вы можете реализовать семантику по крайней мере один раз, отправив получателю подтверждение отправителю, когда сообщение было обработано, и отправитель периодически повторяет попытку, если подтверждение не получено. См. этот вопрос для получения дополнительной информации: Гарантии доставки сообщений Akka

Извините за отсутствие кода, но я использую Scala API, а не Java.

person mattinbits    schedule 27.08.2015
comment
Спасибо @mattinbits (+1) - это имеет смысл. Что касается постоянных акторов, просто любопытно, в каких случаях использования вы хотели бы восстановить точное состояние актера? На мой взгляд, это очень похоже на источники событий и является единственным вариантом использования состояний актеров источников событий. , о котором я могу думать, предназначен для устранения проблем с производством. Мысли? Спасибо еще раз! - person smeeb; 27.08.2015
comment
Это очень похоже на источник событий, цитируя документы по сохранению akka Akka persistence is inspired by and the official replacement of the eventsourced library :) Я не эксперт по вариантам использования, в простейшем случае это может повысить надежность вашего приложения, поскольку состояние может выдерживать перезапуски, но, конечно, вы можете добиться этого с обычной функциональностью базы данных. Но журнал событий позволяет выполнять анализ истории системы, что полезно не только для устранения неполадок. - person mattinbits; 28.08.2015