【问题标题】:akka actor: Patterns.pipe for Eitherakka 演员:Patterns.pipe for Either
【发布时间】:2017-01-17 14:08:08
【问题描述】:

我有这样的方法:

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

如果我想通过管道传输结果,我使用:

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

但我想在 Left 的情况下将结果发送给一个演员,在 Right 的情况下将结果发送给另一个演员。伪代码如下:

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

【问题讨论】:

  • 在这个问题的答案中您还有什么想看的吗?

标签: scala design-patterns akka actor


【解决方案1】:

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)

【讨论】:

    【解决方案2】:

    如果你这样做?

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

    【讨论】:

      猜你喜欢
      • 2014-03-09
      • 2019-01-16
      • 2015-03-25
      • 2012-10-14
      • 1970-01-01
      • 1970-01-01
      • 2019-04-23
      • 1970-01-01
      • 2015-05-06
      相关资源
      最近更新 更多