6

I have the following simple case class hierarchy:

sealed trait Message
case class Foo(bar: Int) extends Message
case class Baz(qux: String) extends Message

And I have a Flow[Message, Message, NotUsed] (from a Websocket-based protocol with codec already in place).

I want to demultiplex this Flow[Message] into separate flows for Foo and Baz types, as those are processed by completely different pathways.

What is the simplest way of doing that? Should be obvious, but I am missing something...

Alexander Temerev
  • 2,654
  • 3
  • 27
  • 34

1 Answers1

6

One way is to use create a RunnableGraph that includes the Flows for each type of message.

val g = RunnableGraph.fromGraph(GraphDSL.create() { implicit builder: GraphDSL.Builder[NotUsed] =>

  val in = Source(...)  // Some message source
  val out = Sink.ignore

  val foo = builder.add(Flow[Message].map (x => x match { case f@Foo(_) => f }))
  val baz = builder.add(Flow[Message].map (x => x match { case b@Baz(_) => b }))
  val partition = builder.add(Partition[Message](2, {
    case Foo(_) => 0
    case Baz(_) => 1
  }))

  partition ~> foo ~> // other Flow[Foo] here ~> out
  partition ~> baz ~> // other Flow[Baz] here ~> out

  ClosedShape
}

g.run()
Alan Effrig
  • 763
  • 4
  • 10
  • Right, Partition. OK, I might do just that. Probably it would benefit to have a built-in combinator for that; perhaps, I'll do a pull request. – Alexander Temerev Nov 05 '16 at 10:37
  • @AlexanderTemerev This may be of interest: http://doc.akka.io/api/akka/2.4/?_ga=1.34091558.643806930.1478315511#akka.stream.scaladsl.Partition – Brian Nov 06 '16 at 15:46
  • The link is dead. Is there any combinator for this yet? – mirelon Oct 23 '20 at 10:18
  • `PartitionWith` is near https://github.com/akka/akka-stream-contrib/blob/master/src/main/scala/akka/stream/contrib/PartitionWith.scala – mirelon Oct 23 '20 at 12:00