如何有条件地将消息传递给特定的下一阶段(以及其他阶段)?

时间:2016-02-05 13:51:12

标签: scala akka typesafe akka-stream

根据传递的消息的某些属性,考虑一个简单的场景,我希望它由特定的下一个阶段处理并继续。

[Source[ActionMessage]] ~> [Flow[ActionMessage, EnrichedActionMessage]] 
~> (eAM: EnrichedActionMessage => eAM.actionType match {
      case ActionA => eAM ~> Flow[EnrichedActionMessage, ReactionA] ~> Sink[ReactionA]
      case ActionB => eAM ~> Flow[EnrichedActionMessage, ReactionB] ~> Sink[ReactionB]
      case ActionC => eAM ~> Flow[EnrichedActionMessage, ReactionC] ~> Sink[ReactionC]
    })

如何实现阶段图阶段的条件路由?

1 个答案:

答案 0 :(得分:1)

此答案基于akka-stream版本2.4.2-RC1。其他版本的API可能略有不同。 sbt可以使用依赖关系:

libraryDependencies += "com.typesafe.akka" %% "akka-stream" % "2.4.2-RC1"

使用Partition组件:

val shape = GraphDSL.create() { implicit b ⇒
  import GraphDSL.Implicits._

  val first = b.add(Sink.foreach[Int](elem ⇒ println("first:\t" + elem)))
  val second = b.add(Sink.foreach[Int](elem ⇒ println("second:\t" + elem)))
  val third = b.add(Sink.foreach[Int](elem ⇒ println("third:\t" + elem)))
  val p = b.add(Partition[Int](3, elem ⇒ elem match {
    case 0                ⇒ 0
    case elem if elem < 0 ⇒ 1
    case elem if elem > 0 ⇒ 2
  }))

  p ~> first
  p ~> second
  p ~> third

  SinkShape(p.in)
}
Source(List(0, 1, 2, -1, 1, -5, 0)).to(shape).run()

/*
Output:
first: 0
third: 1
third: 2
second: -1
third: 1
second: -5
first: 0
*/

如果您希望稍后对元素进行任何处理,则可以返回SinkShape而不是new FanOutShape3(p.in, p.out(0), p.out(1), p.out(2))