Без удаленного доступа это возможно, но все же нежелательно. С удаленным доступом в игре это вообще не сработает.
Если ваша цель состоит в том, чтобы иметь API, который возвращает Future
s, но использует акторов в качестве сантехники, один из подходов может заключаться в том, что API создает внутри своего собственного актора, который он ask
s, а затем возвращает будущее из этого запроса вызывающей стороне. Актер, порожденный вызовом API, гарантированно является локальным для экземпляра API и может взаимодействовать с остальной частью системы акторов через обычный механизм tell
/receive
, так что Future
не отправляется в виде сообщений.
class MyTaskAPI(actorFactory: ActorRefFactory) {
def doSomething(...): Future[SomethingResult] = {
val taskActor = actorFactory.actorOf(Props[MyTaskActor])
taskActor ? DoSomething(...).mapTo[SomethingResult]
}
}
где MyTaskActor
получает DoSomething
, перехватывает отправителя, отправляет запрос на выполнение задачи и, вероятно, become
является состоянием приема для 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 и временным актером, что некоторые могут счесть запахом, но он должен дать представление о том, как реализовать ваш рабочий процесс.
person
Arne Claassen
schedule
16.12.2015