2015-12-16 2 views
1

Я работаю над внедрением небольшого языка для отправки задач на выполнение и контроль выполнения потока. После отправки задачи в мою систему пользователь получает будущее (на котором он может вызывать блокировку get() или flatMap()). Мой вопрос: правильно ли отправлять фьючерсы в сообщениях Akka?Отправляет фьючерсы в сообщениях Akka OK?

Пример: актер А посылает сообщение Response актеру B и Response содержит будущее среди полей. Затем в какой-то момент А выполнит обещание, из которого было создано будущее. После получения ответа B может вызвать функцию flatMap() или get() в любое время.

Я спрашиваю, потому что сообщения Akka должны быть неизменными и работать, даже если актеры находятся на разных JVM. Я не вижу, как мой пример выше может работать, если актеры A и B находятся на разных JVM. Кроме того, есть ли какие-либо проблемы с моим примером, даже если актеры находятся на одной JVM?

Что-то подобное сделано в принятом ответе in this stackoverflow question. Будет ли это работать, если актеры находятся на разных JVM?

ответ

3

Без переустановки это возможно, но все же нецелесообразно. С удалением в игре это не сработает.

Если ваша цель состоит в том, чтобы иметь API, который возвращает Future с, но использует актеров, как сантехника под, один подход может быть то, что API создает свой собственный актер внутренне, что это ask с, а затем возвращает будущее от этого спрашивать вызывающему абоненту. Актер, порожденный вызовом API, гарантированно является локальным для экземпляра API и может связываться с остальной системой актеров посредством обычного механизма tell/receive, так что нет Future s, отправленных в виде сообщений.

class MyTaskAPI(actorFactory: ActorRefFactory) { 

    def doSomething(...): Future[SomethingResult] = { 
    val taskActor = actorFactory.actorOf(Props[MyTaskActor]) 
    taskActor ? DoSomething(...).mapTo[SomethingResult] 
    } 
} 

где MyTaskActor получает DoSomething, фиксирует отправитель, посылает запрос на целевой processince и, вероятно, become S принимающего состояния для SomethingResult, который, наконец, отвечает на захваченный отправитель и останавливает себя. Этот подход создает два участника на запрос, один явно, MyTaskActor и один неявно, обработчик ask, но сохраняет все состояние внутри участников.

В качестве альтернативы, вы можете использовать ActorDSL создать только один актер встроенный в doSomething и использовать захваченный Promise для завершения вместо использования ask:

class MyTaskAPI(system: System) { 

    def doSomething(...): Future[SomethingResult] = { 
    val p = Promise[SomethingResult]() 
    val tmpActor = actor(new Act { 
     become { 
     case msg:SomethingResult => 
      p.success(msg) 
      self.stop() 
     } 
    } 
    system.actorSelection("user/TaskHandler").tell(DoSomething(...), tmpActor) 
    p.future 
    } 
} 

Этот подход немного от верхней части головы и он использует общее значение между API и временным актором, что некоторые могут рассматривать запах, но должны дать представление о том, как реализовать свой рабочий процесс.

+0

Это хороший ответ на вопрос, я отметил его как ответ. Тем не менее, у меня одновременно могут быть миллионы задач в моей системе, поэтому я хотел бы избежать создания участников для каждой задачи для проблем с производительностью. Я сделаю это требование, чтобы соответствующие части системы (участники A и B в моем примере) находились на одной JVM и возвращали фьючерсы. – Davor

+0

Если ваш обработчик просто ставит в очередь задачи, используя обещание/будущее, чтобы сигнализировать о последующей обработке, а затем завершить, все это может быть так же просто, как использовать 'ask' напрямую. таким образом, ваш обработчик все равно получает простое сообщение и вместо того, чтобы создавать «Promise» и немедленно его возвращать, он сохраняет «отправитель» и выполняет «tell» на нем при завершении. Ручки 'ask' превращают это в« Будущее » –

+0

@ArneClaassen: Почему удаленные действующие лица не работают в описываемом им сценарии? –

0

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

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