Паттерн проектирования: как реализовать цепочку акторов, обрабатывающих одно логическое сообщение

Я начинаю смотреть на Akka, и мне интересно, как правильно реализовать конвейер актеров, сотрудничающих для обработки сообщения. Позвольте мне взять пример использования, чтобы проиллюстрировать мой вопрос:

  1. У меня есть сообщение, которое представляет собой «решение», которое должны принять сотрудничающие актеры.

  2. Я хочу иметь возможность создавать несколько "избирателей"; каждый избиратель будет высказывать свое мнение о принимаемом решении (исходя из собственной стратегии и правил).

  3. Я мог бы реализовать разные стратегии для агрегирования мнений разных агентов, но давайте представим, что я хочу принять ПОЛОЖИТЕЛЬНОЕ решение тогда и только тогда, когда ВСЕ агенты в цепочке примут положительное решение.

Как мне реализовать это в акке? Буду ли я реализовывать первого актора, представляющего всю цепочку и получающего сообщение РЕШЕНИЕ? Будет ли у этого актера много детей, если в цепочке есть избиратели? Как отец будет взаимодействовать с детьми и кто будет контролировать ход событий? Будет ли одно и то же сообщение РЕШЕНИЕ передаваться от одного избирателя к другому? Или будет серия взаимодействий между родителем и одним ребенком?

Каковы рекомендуемые шаблоны для этого типа вариантов использования?

Большое спасибо за ваш отзыв!

Оливье


person Olivier Liechti    schedule 17.07.2014    source источник
comment
Читая этот letitcrash.com/post/59190266995/, я думаю, я мог бы реализовать либо шаблон промаха маршрутизации (eaipatterns.com/RoutingTable.html), если Я хочу обработать сообщение в определенном порядке или по шаблону списка получателей (eaipatterns.com/RecipientList.html) в сочетании с шаблоном агрегатора (eaipatterns.com/Aggregator.html), если Я хочу обрабатывать его параллельно. Второе решение подходит для варианта использования «Голосование».   -  person Olivier Liechti    schedule 17.07.2014


Ответы (1)


Вы, наверное, уже ответили сами себе, но я бы сделал следующее:

trait DecisionActor extends Actor

class AbsoluteAgreementActor extends DecisionActor {
  val numberOfVoters = 100
  def receive = {
    case d:Decision = {
      computeDecision(d) pipeTo sender
    }
  }

  def computeDecision(d) = {
    val votes = for {
      i <- 0 until numberOfVoters
      //Naming it for re-usual in case you don't delete it
      voter = context.actorOf(Props[VoterActor], s"Voter $i")           
    } yield {
      voter ? d
    }
    Future.sequence(votes).foldLeft(True)(&&)
  }
}

Затем в главном вы просто задаете решение нужному актеру стратегии. Я добровольно пропустил отмену участников голосования/стратегии, потому что вы можете не захотеть удалять их, если они вам понадобятся снова. Или вы можете не создавать их и не извлекать из пула, общего для всех стратегий. Это зависит от нашего сценария. Затем вы можете создавать различных акторов принятия решений с разными стратегиями, расширяя трейт DecisionActor.

person Diego Martinoia    schedule 10.11.2014