2017-01-17 11 views
2

У меня есть метод, как это:Akka актер: Patterns.pipe для Либо

def myFuture: Future[Either[MyLeft, MyRight]] = Future { 
. 
. 
. 
} 

Если я хочу, чтобы трубы результат, я использую:

Patterns.pipe(myFuture,ec).to(destinationActor) 

Но я хочу в случае левых , отправить результат одному актеру и в случае правого результата отправки другому актеру. псевдокод вроде этого:

MyPatterns.eitherPipe(myFuture,ec).to(leftConsumerActor,rightConsumerActor) 
+0

Есть ли что-нибудь еще вы хотели бы видеть в ответ на этот вопрос? – tkachuko

ответ

3

Исходный код akka сам по себе является хорошим советом, что нужно делать. Посмотрите akka.pattern.PipeToSupport:

def pipeTo(recipient: ActorRef)(implicit sender: ActorRef = Actor.noSender): Future[T] = { 
    future andThen { 
    case Success(r) ⇒ recipient ! r 
    case Failure(f) ⇒ recipient ! Status.Failure(f) 
    } 
} 

Таким образом, мы можем в основном повторно использовать этот подход для нашего случая с диспетчеризацией Either:

val result: Future[Either[Int, Throwable]] = Future.successful(Left(5)) 
result andThen { 
    case Success(Left(value)) => leftActor ! value 
    case Success(Right(exception)) => rightActor ! exception 
    case Failure(exception) => println("Failure") 
} 

Достижения желаемого DSL:

Мы можем попытаться достичь ваш DSL (orPipe() и to (...)) примерно:

trait MyEitherPipeSupport extends PipeToSupport { 

    final class PipeableEitherFuture[L, R](val future: Future[Either[L, R]])(implicit executionContext: ExecutionContext) { 

     def to(leftRef: ActorRef, rightRef: ActorRef, exceptionRef: ActorRef) = future andThen { 
     case Success(Left(value)) ⇒ leftRef ! value 
     case Success(Right(exception)) ⇒ rightRef ! exception 
     case Failure(exception) ⇒ exceptionRef ! Status.Failure(exception) 
     } 
    } 

    implicit def eitherPipe[L, R](future: Future[Either[L, R]])(implicit executionContext: ExecutionContext): PipeableEitherFuture[L, R] = new PipeableEitherFuture(future) 

    } 

Теперь в вашем актера вы просто смешать MyEitherPipeSupport и вы можете написать так:

val result: Future[Either[Int, Throwable]] = Future.successful(Left(5)) 
    eitherPipe(result).to(left, right, anotherOne) 
0

Если вы делаете что-то вроде этого?

myFuture onComplete { 
    case Success(s) => s match { 
     case Right(r) => rightConsumerActor ! r 
     case Left(l) => leftConsumerActor ! l 
    } 
    case Failure(f) => println("failure") 
}