@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
  }
Example #2
0
  @Test
  public void complexGraph() throws Exception {
    // #complex-graph
    RunnableGraph.fromGraph(
        GraphDSL.create(
            builder -> {
              final Outlet<Integer> A = builder.add(Source.single(0)).out();
              final UniformFanOutShape<Integer, Integer> B = builder.add(Broadcast.create(2));
              final UniformFanInShape<Integer, Integer> C = builder.add(Merge.create(2));
              final FlowShape<Integer, Integer> D =
                  builder.add(Flow.of(Integer.class).map(i -> i + 1));
              final UniformFanOutShape<Integer, Integer> E = builder.add(Balance.create(2));
              final UniformFanInShape<Integer, Integer> F = builder.add(Merge.create(2));
              final Inlet<Integer> G = builder.add(Sink.<Integer>foreach(System.out::println)).in();

              builder.from(F).toFanIn(C);
              builder.from(A).viaFanOut(B).viaFanIn(C).toFanIn(F);
              builder.from(B).via(D).viaFanOut(E).toFanIn(F);
              builder.from(E).toInlet(G);
              return ClosedShape.getInstance();
            }));
    // #complex-graph

    // #complex-graph-alt
    RunnableGraph.fromGraph(
        GraphDSL.create(
            builder -> {
              final SourceShape<Integer> A = builder.add(Source.single(0));
              final UniformFanOutShape<Integer, Integer> B = builder.add(Broadcast.create(2));
              final UniformFanInShape<Integer, Integer> C = builder.add(Merge.create(2));
              final FlowShape<Integer, Integer> D =
                  builder.add(Flow.of(Integer.class).map(i -> i + 1));
              final UniformFanOutShape<Integer, Integer> E = builder.add(Balance.create(2));
              final UniformFanInShape<Integer, Integer> F = builder.add(Merge.create(2));
              final SinkShape<Integer> G = builder.add(Sink.foreach(System.out::println));

              builder.from(F.out()).toInlet(C.in(0));
              builder.from(A).toInlet(B.in());
              builder.from(B.out(0)).toInlet(C.in(1));
              builder.from(C.out()).toInlet(F.in(0));
              builder.from(B.out(1)).via(D).toInlet(E.in());
              builder.from(E.out(0)).toInlet(F.in(1));
              builder.from(E.out(1)).to(G);
              return ClosedShape.getInstance();
            }));
    // #complex-graph-alt
  }
Example #3
0
  @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
  }