21

I am trying to understand what does toMat in akka streaming. For example:

val sink1:Sink[Int, Future[Int]]=Sink.fold[Int,Int](0)(_ + _)

val flow=Flow[Int].fold[Int](0){(x,y)=> x+y}

val runnable = Source (1 to 10).viaMat(flow)(Keep.right).toMat(sink1)(Keep.both)
  1. what is use of viaMat vs via?
  2. what is toMat is doing between viaMat to toMat?
  3. what is use of keep.both, does it mean I can have value materialized from previous and the current one if yes then how I can get those values back.

Thanks Arun

Anthony Kong
  • 37,791
  • 46
  • 172
  • 304
ASe
  • 535
  • 5
  • 15
  • It should return as following (keeping both Mat) val runnable:RunnableGraph[(Promise[Option[Int]], Future[Int])] = Source (1 to 10).viaMat(flow)(Keep.right).toMat(sink1)(Keep.both).run() – ASe Mar 05 '16 at 19:15

2 Answers2

31
  1. via is just a shortcut for viaMat(...)(Keep.left), and in fact this is how it's implemented: override def via[T, Mat2](flow: Graph[FlowShape[Out, T], Mat2]): Repr[T] = viaMat(flow)(Keep.left)

  2. toMat is the same as viaMat but for sinks, it lets you keep the materialized value from the left (source/flow) or right (sink) side or both

  3. Keep.both is just an alias for (a:A,b:B) => (a, b), that is a function that takes the two input parameters and return them as a tuple. It's used to have the materialized value of both left and right side when combining two flows (or source and flow or flow and sink etc)

I'll dissect your line of code:

// you're keeping the materialized value of flow
val source2 = Source (1 to 10).viaMat(flow)(Keep.right)
// you're keeping both materialized values, i.e. the one of flow from previous step
// and the one o sink.     
val runnableGraph = source2.toMat(sink)(Keep.both) 
runnableGraph.run() // returns a tuple (flowMatVal, sinkMatVal)

When you join two parts of a flow (i.e source and flow/sink or flow and sink) each of them has a materialized value that you get when you run the flow. The default behaviour when combining with via/to is keeping the left side. If you use viaMat/toMat you can choose to keep the right materialized value or both of them as a tuple.

Giovanni Caporaletti
  • 5,426
  • 2
  • 26
  • 39
  • Thanks. I am not able to understand materialized value, i know source exactly one output and Sink exactly one input, and what is Mat here? The code below suppose to return me tuple correct... can you help me how I can print those: val source1 = Source (1 to 10) val sink:Sink[Int, Future[Int]]=Sink.fold[Int,Int](0)(_ + _) val runnableGraph = source1.toMat(sink)(Keep.both) val x=runnableGraph.run() – ASe Mar 05 '16 at 21:44
  • materialized value is what you get when you do runnableGraph.run(). for example, if you use Sink.fold, it's a future containing the result of the folding. Read this: http://doc.akka.io/docs/akka/2.4.2/general/stream/stream-design.html – Giovanni Caporaletti Mar 05 '16 at 23:15
  • Thanks a lot. I read Materialized values from http://doc.akka.io/docs/akka-stream-and-http-experimental/2.0.3/scala/stream-quickstart.html#materialized-values If I understood correctly - Mat type parameters on Source[+Out, +Mat], Flow[-In, +Out, +Mat] and Sink[-In, +Mat] are run time. – ASe Mar 06 '16 at 00:36
  • a type parameter is known a compile time. The value itself is created at runtime when you run (aka materialize) the stream. Are you going to accept the answer? :P – Giovanni Caporaletti Mar 06 '16 at 10:19
2

some detail I could able to get from akka-user group

https://groups.google.com/forum/#!topic/akka-user/Ofnx_XzWrTU

ASe
  • 535
  • 5
  • 15