Akka 2: Как приостановить обработку сообщений?

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

  • Дроссельный

    . Может быть, Актер, который отправляет электронные письма, но ограничен, чтобы отправлять только одно электронное письмо в секунду.

  • Актер может использовать некоторую систему, которая может обрабатывать одновременную одновременную передачу x-сообщений. Это может быть AsyncHttpClient, у которого есть фиксированный пул потоков, и я не хочу его перегружать.

  • Некоторые внешние ресурсы недоступны, которые необходимы для обработки сообщений (чтение: внешний REST-API)

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

Ответ 1

Общий ответ

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

Дроссельный

Если один компонент обрабатывает сообщения с меньшей скоростью, чем они производятся, в конечном итоге им придется отбрасывать сообщения. Либо используйте ограниченный почтовый ящик, либо поставите менеджера впереди, который отслеживает прогресс работников и переходит в режим "ответ с отрицательным результатом" в периоды стресса.

Когда актор хочет сжать свою собственную скорость вывода, используйте context.system.scheduler.

Это должно ответить на ваши первые две точки.

Восстановление

В периоды, когда требуемый ресурс недоступен, у вас есть два варианта в зависимости от требований: либо внутри очереди сообщений, либо в режиме ответа "не в порядке". Вы также можете смешивать, то есть очередь с определенными ограничениями времени и пространства и сбой при достижении пределов.

Дальнейшие соображения

Всегда держите единицы работы, обработанные актерами настолько малыми, чтобы актер мог реагировать в пределах своих требований к задержке. Последний может быть очень расслабленным (работает в течение нескольких часов бесперебойно) или очень строгим (должен обрабатывать сообщения с частотой кГц).

Ответ 2

case object NextEmail
class EmailActor extends Actor {

self ! NextEmail

  def receive = {
    case NextEmail =>
      sendEmailIfAnyToSend
      context.system.scheduler.scheduleOnce(3 seconds, self, NextEmail)                 
  }
}