根据元素类型选择Akka Streams流程

时间:2017-01-13 05:32:29

标签: scala akka reactive-programming akka-stream

我有一个流程,我想根据其类型选择要在元素上调用的流程。类似的东西:

sealed trait Command
case class CommandA(...) extends Command
case class CommandB(...) extends Command

private def processCommandA: Flow[CommandA, Response, NotUsed] = ???
private def processCommandB: Flow[CommandB, Response, NotUsed] = ???

def processAnyCommand: Flow[Command, Response, NotUsed] = Flow[Command]
  .flatMapConcat {
    case x: CommandA =>
      Source.single(x).via(processCommandA)

    case x: CommandB =>
      Source.single(x).via(processCommandB)
  }

这样可行,但我确信必须有更优雅和有效的方法来实现这一目标,但我只是错过了它。

我想用广播建立一个图表,然后让个人processCommandX忽略他们不理解的命令,然后将它们合并在一起,但这是一个很大的机器并失去了类型的安全性命令是一个密封的特征。

命令是一个密封的特性,可以添加更多的实现,因此对于我来说,获取有关未处理的case子句的编译器帮助非常重要。

1 个答案:

答案 0 :(得分:0)

如果您只能通过Command&处理每个processCommandA类型。 processCommandB流量然后您使用的flatMapConcat技术是最直接的方法。

如果您可以访问两个流程中嵌入的功能,例如如果你的流程看起来像:

private def processFuncA(command : CommandA) = { ... }

private def processCommandA = 
  Flow[CommandA].map(processFuncA)

然后您可以使用基本的Flow#map方法:

def processAnyCommand = 
  Flow[Command] map { _ match {
      case a : CommandA => processFuncA(a)
      case b : CommandB => processFuncB(b)
    }
  }