akka 演员:Patterns.pipe 代表 Either
akka actor: Patterns.pipe for Either
我有这样的方法:
def myFuture: Future[Either[MyLeft, MyRight]] = Future {
.
.
.
}
如果我想通过管道传输结果,我使用:
Patterns.pipe(myFuture,ec).to(destinationActor)
但我想在 Left 的情况下将结果发送给一个演员,在 Right 的情况下将结果发送给另一个演员。像这样的伪代码:
MyPatterns.eitherPipe(myFuture,ec).to(leftConsumerActor,rightConsumerActor)
如果你这样做了?
myFuture onComplete {
case Success(s) => s match {
case Right(r) => rightConsumerActor ! r
case Left(l) => leftConsumerActor ! l
}
case Failure(f) => println("failure")
}
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(eitherPipe() 和 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)
我有这样的方法:
def myFuture: Future[Either[MyLeft, MyRight]] = Future {
.
.
.
}
如果我想通过管道传输结果,我使用:
Patterns.pipe(myFuture,ec).to(destinationActor)
但我想在 Left 的情况下将结果发送给一个演员,在 Right 的情况下将结果发送给另一个演员。像这样的伪代码:
MyPatterns.eitherPipe(myFuture,ec).to(leftConsumerActor,rightConsumerActor)
如果你这样做了?
myFuture onComplete {
case Success(s) => s match {
case Right(r) => rightConsumerActor ! r
case Left(l) => leftConsumerActor ! l
}
case Failure(f) => println("failure")
}
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(eitherPipe() 和 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)