2015-07-31 6 views
0

У меня есть проект, который использует Акка Актеры в scala, и у меня возникают проблемы с актерами, которые обрабатывают и отправляют результаты обратно отправителю.Акка Акка, возвращающая разные типы вывода

Чтобы лучше объяснить, здесь рабочий процесс, что мой проект имеет

  • Commander отправить сбщ в Poller
    • Poller посылает SuccessMessage (Self, List [String]) командующему
  • Commander отправляет список [String] на процессор
    • Процессор отправляет Succe ssMessage (я, File) командующего
  • Commander отправляет файл на пользователе UPLOADER
    • Uploader посылает SuccessMessage (самость, Boolean) командующего
  • и так далее.

По сути, у меня есть два вопроса:

Прямо сейчас, я обернуть все, что возвращается от актера обратно к командиру (супервизор) в SuccessMessage. Это лучший способ сделать это, или есть другой способ обработки многих разных типов возврата?

У SuccessMessage также будет «полезная нагрузка». Я обсуждаю использование дженериков для типа полезной нагрузки или просто сделаю его Option [Any], а затем выполняю много кастингов на стороне командира, прежде чем отправлять его любому игроку (игроку, процессору и т. Д.). Я знаю, что в Java акк актеры просто бросали Object; я должен был бы сделать то же самое?

ответ

2

Там нет «правильного» способа, но я это, как я хотел бы сделать это:

Сделайте сообщения, уникальные для каждой пары типа актера. Оберните фактические данные в этих сообщениях: Poll(something), Polled(result), Process(something), Processed(result), Upload(something) и Uploaded(result).

Тогда либо сделать PollFailed(details), ProcessingFailed(details) и UploadFailed(details) сообщения или положить Option в нормальных результатов сообщений. Мне нравится использовать Option.

Я бы определил эти сообщения в сопутствующих объектах Poller, Processer и Uploader.

получить метод командира тогда вполне достаточно:

def receive = { 
    case Polled(Some(result)) => // handle 
    case Polled(None) => // handle 
    case Processed(Some(result)) => // handle 
    case Processed(None) => // handle 
    case Uploaded(Some(result)) => // handle 
    case Uploaded(None) => // handle 
} 

Держитесь подальше от дженериков. Благодаря стиранию типа вы не можете сопоставить дженерики в методе приема.

+0

Спасибо Quizzie. Проблема в том, что в этом проекте есть несколько командиров (для выполнения разных работ) и нескольких участников для каждого командира, а также добавление сообщений об успешности/сбое, добавлено много дополнительных объектов. Вместо этого, я думаю, лучший вариант может быть просто отличным ... – jstnchng

1

Я не видел код, но я предлагаю сделать две вещи:

  1. создавать различные типы сообщений для успеха. Например.

    • MessagesPolled(List[String]),
    • MessagesProcessed(File)
    • MessagesUploaded и MessagesNotUploaded(Error)

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

  2. Создайте иерархию актеров, чтобы каждый из них отвечал за одну вещь (включая главного актера), например.:

    • Commander имеет ссылки на трех актеров (которые имеют свой собственный рабочий hierarchies):
      • Poller, которые только маршрутизацию сообщений для динамически создаваемых PollerWorker сек
      • Processor, какие только перенаправляет сообщения динамически создаваемых ProcessorWorker s
      • Uploader, который направляет сообщения только динамически созданным UploaderWorker s
    • Commander получает сообщение триггера и посылает первое сообщение Poller с ActorRef к nextStepActor, который, в случае первого сообщения, будет ProcessorWorker

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

Смежные вопросы