使用Akka BroadcastHub时如何防止条目丢失

时间:2019-04-09 07:27:11

标签: akka-stream reactive-streams

我在https://doc.akka.io/docs/akka/current/stream/stream-dynamic.html上找到了以下示例:

// A simple producer that publishes a new "message" every second
Source<String, Cancellable> producer =
    Source.tick(Duration.ofSeconds(1), Duration.ofSeconds(1), "New message");

// Attach a BroadcastHub Sink to the producer. This will materialize to a
// corresponding Source.
// (We need to use toMat and Keep.right since by default the materialized
// value to the left is used)
RunnableGraph<Source<String, NotUsed>> runnableGraph =
    producer.toMat(BroadcastHub.of(String.class, 256), Keep.right());

// By running/materializing the producer, we get back a Source, which
// gives us access to the elements published by the producer.
Source<String, NotUsed> fromProducer = runnableGraph.run(materializer);

// Print out messages from the producer in two independent consumers
fromProducer.runForeach(msg -> System.out.println("consumer1: " + msg), materializer);
fromProducer.runForeach(msg -> System.out.println("consumer2: " + msg), materializer).toCompletableFuture().get();

基本上可以完成它的工作。

我如下更改了“生产者”

// A simple producer that publishes a new "message" every second
Source<String, NotUsed> producer =
    Source.range(1, 100)
          .map(i -> "" + i)
          .wireTap(param -> System.out.println("param: " + param));

// Attach a BroadcastHub Sink to the producer. This will materialize to a
// corresponding Source.
// (We need to use toMat and Keep.right since by default the materialized
// value to the left is used)
RunnableGraph<Source<String, NotUsed>> runnableGraph =
    producer
        .initialDelay(Duration.ofSeconds(1))
        .toMat(BroadcastHub.of(String.class, 256), Keep.right());

// By running/materializing the producer, we get back a Source, which
// gives us access to the elements published by the producer.
Source<String, NotUsed> fromProducer = runnableGraph.run(materializer);

// Print out messages from the producer in two independent consumers
fromProducer.runForeach(msg -> System.out.println("consumer1: " + msg), materializer);
fromProducer.runForeach(msg -> System.out.println("consumer2: " + msg), materializer)
            .toCompletableFuture().get();

上面的代码按预期运行。但是,当我删除“ initialDelay(Duration.ofSeconds(1))”行后,它将不再起作用。

由于使用了wireTap,我看到确实生成了消息,但是消费者没有使用它们。在我看来,这些消息是在附加消费者之前产生的。

我对akka-streams还是很陌生,所以在这里我可能会想念一些东西。

如何在不使用“ initialDelay”的情况下防止这种情况发生?有没有办法在消费者开始“拉”消息之前“阻止”源?

谢谢 汉斯约格

0 个答案:

没有答案