@Test public void demonstrateBroadcast() { final Sink<Author, CompletionStage<Done>> writeAuthors = Sink.ignore(); final Sink<Hashtag, CompletionStage<Done>> writeHashtags = Sink.ignore(); // #flow-graph-broadcast RunnableGraph.fromGraph( GraphDSL.create( b -> { final UniformFanOutShape<Tweet, Tweet> bcast = b.add(Broadcast.create(2)); final FlowShape<Tweet, Author> toAuthor = b.add(Flow.of(Tweet.class).map(t -> t.author)); final FlowShape<Tweet, Hashtag> toTags = b.add( Flow.of(Tweet.class) .mapConcat(t -> new ArrayList<Hashtag>(t.hashtags()))); final SinkShape<Author> authors = b.add(writeAuthors); final SinkShape<Hashtag> hashtags = b.add(writeHashtags); b.from(b.add(tweets)).viaFanOut(bcast).via(toAuthor).to(authors); b.from(bcast).via(toTags).to(hashtags); return ClosedShape.getInstance(); })) .run(mat); // #flow-graph-broadcast }
@Test public void demonstrateSlowProcessing() { // #tweets-slow-consumption-dropHead tweets .buffer(10, OverflowStrategy.dropHead()) .map(t -> slowComputation(t)) .runWith(Sink.ignore(), mat); // #tweets-slow-consumption-dropHead }
public void demonstrateACustomMaterializedValue() throws Exception { // tests: RunnableGraph<CompletionStage<Integer>> flow = Source.from(Arrays.asList(1, 2, 3)) .viaMat(new FirstValue(), Keep.right()) .to(Sink.ignore()); CompletionStage<Integer> result = flow.run(mat); assertEquals(new Integer(1), result.toCompletableFuture().get(3, TimeUnit.SECONDS)); }
@Test public void partialGraph() throws Exception { // #partial-graph final Graph<FlowShape<Integer, Integer>, NotUsed> partial = GraphDSL.create( builder -> { final UniformFanOutShape<Integer, Integer> B = builder.add(Broadcast.create(2)); final UniformFanInShape<Integer, Integer> C = builder.add(Merge.create(2)); final UniformFanOutShape<Integer, Integer> E = builder.add(Balance.create(2)); final UniformFanInShape<Integer, Integer> F = builder.add(Merge.create(2)); builder.from(F.out()).toInlet(C.in(0)); builder.from(B).viaFanIn(C).toFanIn(F); builder .from(B) .via(builder.add(Flow.of(Integer.class).map(i -> i + 1))) .viaFanOut(E) .toFanIn(F); return new FlowShape<Integer, Integer>(B.in(), E.out(1)); }); // #partial-graph // #partial-use Source.single(0).via(partial).to(Sink.ignore()); // #partial-use // #partial-flow-dsl // Convert the partial graph of FlowShape to a Flow to get // access to the fluid DSL (for example to be able to call .filter()) final Flow<Integer, Integer, NotUsed> flow = Flow.fromGraph(partial); // Simple way to create a graph backed Source final Source<Integer, NotUsed> source = Source.fromGraph( GraphDSL.create( builder -> { final UniformFanInShape<Integer, Integer> merge = builder.add(Merge.create(2)); builder.from(builder.add(Source.single(0))).toFanIn(merge); builder.from(builder.add(Source.from(Arrays.asList(2, 3, 4)))).toFanIn(merge); // Exposing exactly one output port return new SourceShape<Integer>(merge.out()); })); // Building a Sink with a nested Flow, using the fluid DSL final Sink<Integer, NotUsed> sink = Flow.of(Integer.class).map(i -> i * 2).drop(10).named("nestedFlow").to(Sink.head()); // Putting all together final RunnableGraph<NotUsed> closed = source.via(flow.filter(i -> i > 1)).to(sink); // #partial-flow-dsl }