Повторить/воспроизвести неудачные сообщения в AKKA

Я использую AKKA.NET в своем текущем проекте .NET.

Мой вопрос заключается в следующем: как опытные разработчики AKKA реализуют шаблон повторного сообщения о сбое, используя последние библиотеки AKKA для Java или .NET?

Вот еще некоторые подробности.

Я хочу убедиться, что ошибочное сообщение (т.е. сообщение, полученное актером, приводящее к исключению) повторяется/повторяется несколько раз с временным интервалом между каждым. Обычно актор перезапускается неудачным сообщением и отбрасывается.

Я написал свой собственный небольшой вспомогательный метод, чтобы решить эту проблему:

   public void WithRetries(int noSeconds, IUntypedActorContext context, IActorRef receiver, IActorRef sender, Object message, Action action)
    {
            try
            {
                action();
            }
            catch (Exception e)
            {
                context.System.Scheduler.ScheduleTellOnce(new TimeSpan(0, 0, noSeconds), receiver, message, sender);
                throw;
            }
        }
    }

Теперь мои актеры обычно выглядят так:

 Receive<SomeMessage>(msg =>
        {

            ActorHelper.Instance.WithRetries(-1, Context, Self, Sender, msg, () =>     {
              ...here comes the actual message processing  
            });
        });

Мне нравится приведенное выше решение, потому что оно простое. Однако мне не нравится, что это добавляет еще один уровень косвенности в мой код, и код становится немного более беспорядочным, если я использую этот вспомогательный метод во многих местах. Кроме того, он имеет некоторые ограничения. Во-первых, количество повторных попыток не регулируется вспомогательным методом. Это регулируется стратегией надзора супервайзера, которая, я считаю, беспорядочна. Кроме того, временной интервал фиксирован, тогда как в некоторых случаях мне бы хотелось, чтобы временной интервал увеличивался с каждой повторной попыткой.

Я бы предпочел что-то, что можно настроить с помощью HOCON. Или что-то, что может быть применено в качестве перекрестного концерна.

Я вижу различные предложения для AKKA для Scala, AKKA для Java и AKKA.NET. Я видел примеры с маршрутизаторами, примеры с автоматическим выключателем (например, http://getakka.net/docs/CircuitBreaker#examples) и так далее. Я также видел несколько примеров, использующих ту же идею, что и выше. Но мне кажется, что должно быть еще проще. Возможно, это связано с использованием AKKA Persistence и событий.

Итак, повторю мой вопрос: как опытные AKKA-разработчики реализуют шаблон повторного сообщения о сбое, используя последние библиотеки AKKA для Java или .NET?


person Nikola Schou    schedule 01.09.2016    source источник
comment
Как это сделать Retry/replay в случае неудачного сообщения в java с akka. Если кто знает помогите пожалуйста.   -  person Mithun Debnath    schedule 16.02.2017


Ответы (2)


Я когда-то просматривал это в прошлом году - я нахожусь вдали от своей машины для разработки, поэтому не могу проверить, так что все это исходит из памяти:

Кажется, я помню, что решением этой проблемы было сочетание стратегий хранения и наблюдения, а также крючков жизненного цикла :)

Я думаю, что вы можете обернуть код своего дочернего актора в try-catch, затем, в случае ошибки, спрятать сообщение и повторно выдать исключение, чтобы оно обрабатывалось супервизором и всем обычным надзором стратегии вступают в игру. Я думаю, что вы скорее продолжите, чем перезапустите. Затем в соответствующем сообщении жизненного цикла (onresume?!) удалите сообщения, которые должны означать, что неудачное сообщение обрабатывается снова.

Теперь это не так уж отличается от того, что вы уже опубликовали выше, так что, надеюсь, у кого-то есть лучшее решение :)

person tomliversidge    schedule 01.09.2016
comment
Спасибо, по крайней мере, я знаю, что другие люди пришли к такому же выводу, как и я. - person Nikola Schou; 01.09.2016
comment
@NikolaSchou Я столкнулся с той же проблемой. Можете ли вы указать мне пример кода, который я могу изучить. Я новичок в Акка/Скала. Так что нужна небольшая помощь. Спасибо. - person Som Bhattacharyya; 09.08.2017
comment
Что ж, @SomBhattacharyya, вы можете взять код, который я написал выше, поскольку он действительно работает так, как должен. Я только спрашиваю, пришли ли другие люди к другим решениям, чем я. - person Nikola Schou; 14.08.2017

Это может быть поздно. Но другое решение состоит в том, чтобы передать команду (или основные параметры) конструктору актора и отправить команду islef при создании и использовать директиву Restart.

// Scala code
class ResilientActor(cmd:Comman) extends Actor {
  def receive = {
     ...
  }
  self ! cmd
}

...

override val supervisorStrategy = OneForOneStrategy(maxNrOfRetries = 3){
  case _: SomeRetryableException => Restart
  case t => super.supervisorStrategy.decider.applyOrElse(t, (_:Any) => Escalate)
}
person gervais.b    schedule 09.11.2016