Akka Steam Graphs — A first Java example
Background
Asynchronous, Non blocking applications
Asynchronous and non blocking is a nice way to write applications. You can read up a bit about “Asynchronous and non blocking” from these pages
Reactive Streams
From Wikipedia link below
Reactive Streams is an initiative to provide a standard for asynchronous stream processing with non-blocking back pressure
One way of writing an Asynchronous/Non blocking application, is by using “Reactive Steams”.
Akka streams
Akka Streams is one implementation of“Reactive Steams”.
Under the cover it uses actors and messages.
Having worked with Erlang for some time, looking at Akka was logical for me.
Read up on Akka Streams here:
Akka Stream Graphs
From Akka website:
Considering linear Flows to be like roads, we can picture graph operations as junctions: multiple flows being connected at a single point.
Read up on Akka Stream Graphs here:
First Graph code example from Akka Site
The above is copied “as is” from the Akka site : https://doc.akka.io/docs/akka/current/stream/stream-graphs.html
Understanding the example
Code Modifications
- Added a materializer to run the Graph
final ActorSystem system = ActorSystem.create("QuickStart");
final Materializer materializer = ActorMaterializer.create(system);
- Changed source to have one element to make it easy to understand the flow
final Source<Integer, NotUsed> in = Source.from(Arrays.asList(1));
- Made the Sink write to standard out for debug
Sink<Object, CompletionStage<Done>> sink = Sink.foreach(v -> System.out.println("Val : " + v));
- Changed “grouped” to no group i.e. print as the flow happens
.via(builder.add(f3.grouped(1000))) changed to .via(builder.add(f3))
- Added some code to run the Graph
completionStageRunnableGraph.run(materializer).thenRun(system::terminate);
Modified Code
Code output
Val : 31
Val : 41
Understanding

- Our Source is has one number “1”
- We go through Function-1 which adds 10, we now have a value of 11
- Then we have a broadcast with 2 paths
- First path is Function-1 which adds 20, we now have a value of 31(11+20), in the first path
- Second path is Function-4 which adds 30, we now have a value of 41(11+30), in the second path
- We then merge
- Then we have run though Function-3 which does a “toString”
- Then we have the Sink “out” which prints our values
Val : 31
Val : 41
Further Modifying the example
Modifications with one more path
- Added a new flow Flow 5
final Flow<Integer, Integer, NotUsed> f5 = Flow.of(Integer.class).map(elem -> elem + 40)
- Changed the Broadcast to be 3 paths
builder.add(Broadcast.create(3));
- Changed the Merge to be 3 paths also
builder.add(Merge.create(3));
- Added the Flow 5 to the broadcast and merge
builder.from(bcast)
.via(builder.add(f5)) // + 40 -> 11 + 40 -> 51
.toFanIn(merge);
Modified Code
Code output
Val : 31
Val : 41
Val : 51
Understanding

- Our Source is has one number “1”
- We go through Function-1 which adds 10, we now have a value of 11
- Then we have a broadcast with 3paths
- First path is Function-1 which adds 20, we now have a value of 31(11+20), in the first path
- Second path is Function-4 which adds 30, we now have a value of 41(11+30), in the second path
- Second path is Function-5 which adds 40, we now have a value of 51(11+40), in the third path
- We then merge
- Then we have run though Function-3 which does a “toString”
- Then we have the Sink “out” which prints our values
Val : 31
Val : 41
Val : 51
Conclusion
Streams are a powerful way to develop modern reactive applications.
Akka Graphs add another powerful layer to stream processing.
What do you feel ? Please add in comments section below.