Ожидание нескольких сообщений Akka FSM

У меня есть актор Akka FSM, который запускает следующий псевдокод после получения сообщения в ReadyState

lookupA ! Wrapper(Lookup("A"))
lookupB ! Wrapper(Lookup("B"))
lookupC ! Wrapper(Lookup("C"))
goto(LookingUpDataState) using DataFound(a = None, b = None, c = None)

Затем актор ожидает ответов, которые могут быть либо FullResult[T] (расширение ServiceResult[T]), либо Empty (расширение ServiceResult[Nothing]). Успешные результаты поиска используются для заполнения полей экземпляра DataFound, а пустые результаты поиска приводят к регистрации сообщения об ошибке и завершению действия актора.

Мой вопрос заключается в следующем: как я могу определить, какой поиск не удался, чтобы я мог зарегистрировать ошибку или вернуться к значению по умолчанию? Все, что я могу придумать, это изучить ActorRef отправителя (хакерский подход) или добавить уникальное поле идентификатора ко всем сообщениям (высокие накладные расходы).

Это простая проблема, которую можно решить с помощью Ask и Futures. Существует ли идиоматическое решение Akka?


person pkinsky    schedule 21.07.2014    source источник


Ответы (1)


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

  • выполнение запросов по порядку, поэтому отправьте A, дождитесь ответа A, отправьте B ... Но это ужасно - как в ненужной последовательности.
  • используйте шаблон ask, так что вы раскрутите (внутренне так работает ask) 3 актера, и они завершат «свое собственное» будущее. Так что это также имеет некоторые затраты для отправителя, потому что он должен запускать этих субъектов специального назначения (меньше, чем обычный актор, но все же).
  • Да, вам нужно будет как-то пометить эти сообщения. Таким образом, вы отправляете какой-то идентификатор, и ответ должен содержать тот же идентификатор, тогда вы знаете, что это «о, это ответ для A» и т. Д. Я бы сказал, что это рекомендуемый способ пойти сюда.
  • в Akka доступен шаблон contrib под названием Aggregator, который предназначен для этого варианта использования, поэтому вы можете проверить его: http://doc.akka.io/docs/akka/2.3.4/contrib/aggregator.html Однако, если вы нравится это или нет, это во многом вопрос личного вкуса, я думаю.

Мой личный фаворит (мы обычно избегаем ask) будет помечать запросы тегами Envelope(id, payload), чтобы ответы также можно было обернуть такими Envelope(id, response). Если вы решите называть их просто конвертом или чем-то еще с терминологией предметной области, решать вам.

Надеюсь это поможет.

person Konrad 'ktoso' Malawski    schedule 22.07.2014