Акка 2: Как приостановить обработку сообщений? - PullRequest
10 голосов
/ 07 марта 2012

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

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

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

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

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

Ответы [ 2 ]

7 голосов
/ 08 марта 2012

Общий ответ

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

Throttling

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

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

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

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

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

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

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

2 голосов
/ 08 марта 2012
case object NextEmail
class EmailActor extends Actor {

self ! NextEmail

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