akka Actors — Реализация рабочих процессов, действий или диалогов

Допустим, я хочу реализовать ProgrammableRemote в акке —

   ProgrammableRemote

    - WatchMovie
          1. Tv ! PowerOn
          1.1 Tv ! ChangeInput 3
          2. DVD ! PowerOn
          3. AVReceiver ! PowerOn
          3.1 AVReceiver ! SetInput 'DVD'

Я мог бы использовать фьючерсы для последовательности 1 и 1.1 (и 3. и 3.1). Однако это приведет к тому, что 1.1 будет выполняться в потоке, отдельном от потока приема актора. Если я использую «pipeTo self», мне нужно будет обработать регистр сообщения «PowerOn Completed» от телевизора в методе «receive».

В идеале я хотел бы иметь возможность расширить получение актера, чтобы динамически обрабатывать ответы от других актеров на основе невыполненных запросов. Есть ли какое-нибудь решение в akka для этого варианта использования?


person akh    schedule 21.10.2012    source источник


Ответы (1)


Я бы просто отправлял сообщения, их порядок сохраняется для каждого отправителя, поэтому, если вы получите ChangeInput до того, как он будет включен, вам все равно придется иметь дело с этим. Используйте «становиться» или Akka FSM DSL для кодирования различных состояний и возможных команд в каждом состоянии.

person Viktor Klang    schedule 21.10.2012
comment
Ваше предложение более актуально для реализации самого актера «ТВ». Чтобы реализовать ProgrammableRemoteActor, мне все еще нужно найти способ дождаться включения телевизора, прежде чем я отправлю сообщение «ChangeInput». Это важно, поскольку «Телевизор» может быть реальным устройством, и, следовательно, сообщение может быть потеряно при отправке, если телевизор не полностью включен. Я думаю, «стать» все равно поможет. Но похоже, что этот шаблон очень распространен для взаимодействия типа запрос/ответ и заслуживает первоклассного синтаксиса. - person akh; 21.10.2012
comment
Имхо, это неправда, так как кто-то другой может выключить телевизор через наносекунду после включения телевизора. Я бы просто отправил два сообщения, в реальном мире пульт не знает, работает сигнал или нет. - person Viktor Klang; 21.10.2012
comment
Для сохранения диалогового контекста очень полезно просто создать дочернего актора, который будет с этим иметь дело. См. Saga в терминологии CQRS. - person Viktor Klang; 21.10.2012
comment
Я думаю, что аналогия с телевизором и пультом дистанционного управления заходит так далеко. Однако ясно, что у нас может возникнуть ситуация, когда мы ждем ответа на первый исходящий запрос, прежде чем отправлять следующий (например, на второе сообщение может повлиять ответ от первого).‹br›I мог бы сделать: стать { case response =› ... } orElse mainReceive. Это будет работать, когда у нас есть только невыполненный запрос. Что, если я хочу иметь возможность одновременно отправлять несколько запросов различным субъектам и ждать их только тогда, когда мне нужно использовать результаты. - person akh; 21.10.2012
comment
По сути, у вас есть 3 варианта: 1) иметь идентификацию для потока и сохранить карту открытых разговоров. 2) Создайте ребенка для каждого разговора. или 3) Используйте аск и фьючерсы. Можно представить себе некий DSL, который порождает дочерний актор и работает с хитрыми битами, обеспечивая при этом декларативный способ работы с потоком информации. - person Viktor Klang; 22.10.2012
comment
Я напишу, чтобы обсудить три варианта в отдельных комментариях. - person akh; 03.11.2012
comment
Использование идентификатора с картой для открытых диалогов будет не очень прозрачным. Наличие дочернего актера для каждого разговора должно работать, но опять же не очень прозрачно. Использование фьючерсов: однако я хочу иметь возможность писать последовательный код на поверхности, но прозрачно использовать преимущества асинхронной природы модели акторов. fv1 = a1.req1(p1,...) fv2 = a2.req2(p11,...) и так далее. Теперь, когда я выполняю некоторые вычисления, для которых требуются значения, возвращаемые fv1 и fv2, v3 = некоторое выражение (fv1, fv2), он должен прозрачно приостанавливать поток актора до тех пор, пока fv1 не будет доступен, а fv2 не будет доступен. - person akh; 03.11.2012
comment
Если выражение включает в себя в основном вычисления (без ввода-вывода), мы можем решить его, выполнив получение на каждом канале будущего. Однако выражение может включать запросы к другим субъектам. Чтобы добиться максимального параллелизма ввода-вывода, мы хотим иметь как можно больше необработанных запросов. Задача здесь состоит в том, чтобы иметь возможность выполнять те части выражений, которые готовы, и по мере поступления ответов от акторов оценивать выражение. Будущие AFAIK могут быть смоделированы как монады, но тогда это требует последовательного порядка оценки. - person akh; 03.11.2012
comment
Некоторые утверждают, что акторная модель представляет собой настоящий объектно-ориентированный подход — она точно моделирует инкапсуляцию и передачу сообщений. Однако, если мы пытаемся преобразовать существующее объектно-ориентированное приложение в полностью акторную модель, нам придется моделировать каждый вызов метода как сообщение, а возвращаемое значение как «будущее». Это потребует блокировки после отправки каждого сообщения, какая модель актора не рекомендуется, поскольку это может привести к взаимоблокировке. Если мы избегаем блокировки, нам нужно написать приложение, чтобы иметь дело с асинхронной природой модели акторов. - person akh; 03.11.2012
comment
В идеале мы должны иметь возможность взять существующее объектно-ориентированное приложение и прозрачно преобразовать его в акторную модель (скажем, путем грамотного использования динамических прокси и АОП) и исключить использование блокировок и других примитивов синхронизации. - person akh; 03.11.2012
comment
Нет, вы не можете тривиально преобразовать объектно-ориентированную модель в акторную, потому что объектно-ориентированная программа пытается обмануть вас, заставив думать, что операции чтения дешевы, чего в распределенной системе нет. - person Viktor Klang; 04.11.2012
comment
Под ООП я подразумеваю то, как Java, .NET, C++ определяет ООП. - person Viktor Klang; 04.11.2012
comment
Я понимаю, что переход от традиционного кода в стиле объектно-ориентированного программирования к акторной модели нетривиален. То, что я пытаюсь увидеть, возможно ли это вообще (с точки зрения вычислительной модели)? Будет ли это практично или нет (с точки зрения производительности) - это другой вопрос. Например, кэширующий прокси-актор может поддерживать иллюзию дешевого чтения. - person akh; 04.11.2012
comment
TypeActor действительно помогает, но я думаю, что проблема все еще связана с несколькими нерешенными задачами будущего. Интерпретатор акта 1 может оценивать аргументы функции параллельно и блокировать их только при необходимости. Это то, о чем я говорил. В Lisp/Scheme легко изменить схему оценки (ленивую, нетерпеливую, основанную на будущем и т. д.) с минимальными изменениями в интерпретаторе. Насчет Scala не уверен. - person akh; 05.11.2012
comment
Ну, вы вольны использовать любой язык, какой захотите. - person Viktor Klang; 05.11.2012