33

Can someone explain clearly what are the difference between those 4 methods ? When is it more appropriate to use each one ? Also generally speaking what is the name of this Group of method? Are there more method that does the same job ? A link to the scaladoc could also help.

-D-

MaatDeamon
  • 9,532
  • 9
  • 60
  • 127

1 Answers1

77

All these methods are necessary to join two streams into one stream. For example, you can create a Source out of a Source and a Flow, or you can create a Sink out of a Flow and a Sink, or you can create a Flow out of two Flows.

For this, there are two basic operations, to and via. The former allows one to connect either a Source or a Flow to a Sink, while the latter allows to connect a Source or a Flow to a Flow:

source.to(sink)   ->  runnable graph
flow.to(sink)     ->  sink

source.via(flow)  ->  source
flow1.via(flow2)  ->  flow

For the reference, a runnable graph is a fully connected reactive stream which is ready to be materialized and executed.

*Mat versions of various operations allow one to specify how materialized values of streams included in the operation should be combined. As you may know, each stream has a materialized value which can be obtained when the stream is materialized. For example, Source.queue yields a queue object which can be used by another part of your program to emit elements into the running stream.

By default to and via on sources and flows only keeps the materialized value of the stream it is called on, ignoring the materialized value of its argument:

source.to(sink)    yields   mat.value of source
source.via(flow)   yields   mat.value of source

flow.to(sink)      yields   mat.value of flow
flow1.via(flow2)   yields   mat.value of flow1

Sometimes, however, you need to keep both materialized values or to combined them somehow. That's when Mat variants of methods are needed. They allow you to specify the combining function which takes materialized values of both operands and returns a materialized value of the combined stream:

source.to(sink)    equivalent to   source.toMat(sink)(Keep.left)
flow1.via(flow2)   equivalent to   flow1.viaMat(flow2)(Keep.left)

For example, to keep both materialized values, you can use Keep.both method, or if you only need the mat.value of the "right" operand, you can use Keep.right method:

source.toMat(sink)(Keep.both)   yields   a tuple (mat.value of source, mat.value of sink)
Vladimir Matveev
  • 120,085
  • 34
  • 287
  • 296
  • 2
    This is a great great answer, very neat ! Meanwhile just to clarify one point. I find it strange that the default as in source.to(sink) keep the source value (left). If the sink is a fold, I believe I would be interested in the result of the fold. In this case the only way would be to use toMat. Actually I just can't see the default is to use the left value while the most frequent use case is to go on with the right value. Maybe you could toss few comments on that. I might not think of it the right way. – MaatDeamon Jun 21 '16 at 14:00
  • @MaatDeamon, I don't know exact reasons for that, but it may be connected with the fact that all these operations are implemented generically in a supertrait of both `Source` and `Flow`, therefore some parameters of some operations which make sense for `Flow`s may make less sense for `Source`s, and vice versa. – Vladimir Matveev Jun 21 '16 at 14:03
  • 2
    It is a good answers, except the some Terms is not correct. like "all these methods are necessary to join two streams into one stream" should be "sll these methods are necessary to join two stream operators into one stream operator". and "each stream has a materialized value" should be "each stream operator has a materialized value". Reason is, Source, Flow, Sink are just operator, they compose the final Stream – user11882433 Aug 05 '19 at 03:32
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/low-quality-posts/23710003) – L. F. Aug 05 '19 at 03:52