Jack Thomson
Jack Thomson

Reputation: 193

How does materialised value work in Akka Stream

I understood that when I run an Akka Stream graph, it will materialised the most right component.

But doing this:

Source.range(1,100).to(Sink.reduce((a,b) -> a+b)).run(materializer);

Will materialise NotUsed though the most left component is a sink that returns integer.

However, doing the same with runWith works fine:

Source.range(1, 100).runWith(Sink.reduce((a, b) -> a + b), materializer)
                .thenAccept(value -> LOGGER.info("The final value is {}", value));

What is it that I didn't understand well about the run method?

Upvotes: 0

Views: 137

Answers (1)

Jeffrey Chung
Jeffrey Chung

Reputation: 19497

By default, to retains the materialized value of the stream operator that calls that method. In your example...

Source.range(1, 100).to(Sink.reduce((a, b) -> a + b)).run(materializer);
//                  ^

...the Source invokes to, so calling run on the stream returns the materialized value of the Source, which is NotUsed, and ignores the materialized value of the Sink. This is the equivalent of running source.toMat(sink, Keep.left()).

In contrast, calling runWith instead of to and run in this case returns the materialized value of the Sink, because runWith is a shorthand way of using Keep.right().

From the documentation:

final CompletionStage<Integer> sum = tweets.map(t -> 1).runWith(sumSink, system);

runWith() is a convenience method that automatically ignores the materialized value of any other operators except those appended by the runWith() itself. In the above example it translates to using Keep.right as the combiner for materialized values.

Upvotes: 2

Related Questions