Below is code I’ve written to try an output the sum of each akka message received which has been edited from this guide :
https://doc.akka.io/docs/akka/current/stream/stream-flows-and-basics.html
import akka.Done; import akka.NotUsed; import akka.actor.ActorRef; import akka.actor.typed.ActorSystem; import akka.actor.typed.javadsl.Behaviors; import akka.japi.Pair; import akka.stream.CompletionStrategy; import akka.stream.OverflowStrategy; import akka.stream.javadsl.Flow; import akka.stream.javadsl.Sink; import akka.stream.javadsl.Source; import java.util.ArrayList; import java.util.List; import java.util.Optional; public class AkkaSourceTesting { public static void main(String args[]){ ActorSystem actorSystem = ActorSystem.create(Behaviors.empty() , "actorSystem"); Source<Integer, ActorRef> matValuePoweredSource = Source.actorRef( elem -> { // complete stream immediately if we send it Done if (elem == Done.done()) return Optional.of(CompletionStrategy.immediately()); else return Optional.empty(); }, // never fail the stream because of a message elem -> Optional.empty(), 100, OverflowStrategy.fail()); Pair<ActorRef, Source<Integer, NotUsed>> actorRefSourcePair = matValuePoweredSource.preMaterialize(actorSystem); actorRefSourcePair.first().tell(1, ActorRef.noSender()); actorRefSourcePair.first().tell(1, ActorRef.noSender()); actorRefSourcePair.first().tell(1, ActorRef.noSender()); Flow<Integer, Integer, NotUsed> groupedFlow = Flow.of(Integer.class) .grouped(2) .map(value -> { List<Integer> newList = new ArrayList<>(value); return newList; }) .mapConcat(value -> value); // pass source around for materialization actorRefSourcePair.second().via(Flow.of(Integer.class).via(groupedFlow).fold(0, (res, element) -> res + element)).runWith(Sink.foreach(System.out::println), actorSystem); } }
The fold operation seems to cause nothing to outputted on the console.
However if I use
actorRefSourcePair.second().via(Flow.of(Integer.class).via(groupedFlow).map(x -> x * 2)).runWith(Sink.foreach(System.out::println), actorSystem);
instead of
actorRefSourcePair.second().via(Flow.of(Integer.class).via(groupedFlow).fold(0, (res, element) -> res + element)).runWith(Sink.foreach(System.out::println), actorSystem);
Then the following is outputted :
2 2
I’m attempting to group a list and perform a fold operation on each of the groups but the fold is not even being executed. Have I missed a step ?
Advertisement
Answer
Flow.fold
does not emit a value until the upstream completes.
Also note that your groupedFlow
is an identity flow: it could be removed without changing anything:
grouped
takes each successive pair of elements and bundles them into aList
- The
map
stage converts thatList
to anArrayList
mapConcat
unwraps theArrayList
and emits the elements
The clearest expression of what you’re looking for (a stream of the sum of pairs of successive groups of 2) in Java is probably along the lines of
actorRefSourcePair.second() .grouped(2) .map(twoList -> twoList.stream().reduce(0, Integer::sum)) .runWith(Sink.foreach(System.out::println), actorSystem);