BroadcastHub不等待Source的首次实现

时间:2019-11-21 12:04:17

标签: akka-stream

这是 Akka Streams 文档关于Source BroadcastHublink)实现的Sink的内容:

  

生成的Source可以实现多次,每次实现都有效地附加了一个新订户。如果没有订阅者连接到该集线器,那么它将不会丢弃任何元素,而是对上游生产者施加反压,直到订阅者到达为止。

因此,我希望这样:

 Source<String, NotUsed> bcast =
            Source.from(Arrays.asList("1", "2", "3"))
                  .log("before broadcasting")
                  .runWith(BroadcastHub.of(String.class), materializer);

 bcast.log("after broadcasting")
      .runWith(Sink.ignore(), materializer);

将有效地对BroadcastHub Sink的上游进行反压,直到bcast Source至少实现一次,但事实并非如此。如果运行以上命令,输出为:

[before broadcasting] Element: 1
[before broadcasting] Element: 2
[before broadcasting] Element: 3
[before broadcasting] Upstream finished.
[after broadcasting] Upstream finished.

与文档相反,因为元素被有效地删除并且从不广播。如果我这样限制Broadcast Sink的缓冲区:

        Source<String, NotUsed> bcast =
            Source.from(Arrays.asList("1", "2", "3"))
                  .log("before broadcasting")
                  .runWith(BroadcastHub.of(String.class, 2), materializer); //buffer smaller than number of events

然后广播所有元素:

[before broadcasting] Element: 1
[before broadcasting] Element: 2
[after broadcasting] Element: 1
[after broadcasting] Element: 2
[before broadcasting] Element: 3
[before broadcasting] Upstream finished.
[after broadcasting] Element: 3
[after broadcasting] Upstream finished.

我认为它是错误还是文档具有误导性?

1 个答案:

答案 0 :(得分:0)

我不是Akka专家,但是,我在Scala中进行了更多测试。 (并且也从字符串更改为整数)

通过对流进行节流以确保第二个流在集线器上游源完成之前就已连接,就可以像预期的那样工作。

如果将100毫秒的延迟更改为10毫秒,则会观察到第二个响应(如下)。

我没有检查来源,但是...

看起来元素确实已由广播集线器缓冲,但是如果上游源已在第二接收器连接时完成,则表明上游已完成并完成,而没有接收到缓冲的元素。

我不确定这是文档问题还是错误。

  val sink=BroadcastHub.sink[Int]// (2)

  //10 millis  
  val bcast = Source(1 to (3)).throttle(2,100.millis).
    log("before broadcasting").
    runWith(sink)

  //Thread.sleep(1000) doesnt make any difference
  bcast.log("after broadcasting").runWith(Sink.ignore)

100 ms的油门结果

[DEBUG] [01/29/2020 10:48:50.168] [broadcastHubTest-akka.actor.default-dispatcher-4] [akka.stream.Log(akka://broadcastHubTest/system/StreamSupervisor-0)] [before broadcasting] Element: 1
[DEBUG] [01/29/2020 10:48:50.168] [broadcastHubTest-akka.actor.default-dispatcher-4] [akka.stream.Log(akka://broadcastHubTest/system/StreamSupervisor-0)] [before broadcasting] Element: 2
[DEBUG] [01/29/2020 10:48:50.172] [broadcastHubTest-akka.actor.default-dispatcher-2] [akka.stream.Log(akka://broadcastHubTest/system/StreamSupervisor-0)] [after broadcasting] Element: 1
[DEBUG] [01/29/2020 10:48:50.172] [broadcastHubTest-akka.actor.default-dispatcher-2] [akka.stream.Log(akka://broadcastHubTest/system/StreamSupervisor-0)] [after broadcasting] Element: 2
[DEBUG] [01/29/2020 10:48:50.233] [broadcastHubTest-akka.actor.default-dispatcher-4] [akka.stream.Log(akka://broadcastHubTest/system/StreamSupervisor-0)] [before broadcasting] Element: 3
[DEBUG] [01/29/2020 10:48:50.233] [broadcastHubTest-akka.actor.default-dispatcher-4] [akka.stream.Log(akka://broadcastHubTest/system/StreamSupervisor-0)] [before broadcasting] Upstream finished.
[DEBUG] [01/29/2020 10:48:50.233] [broadcastHubTest-akka.actor.default-dispatcher-3] [akka.stream.Log(akka://broadcastHubTest/system/StreamSupervisor-0)] [after broadcasting] Element: 3
[DEBUG] [01/29/2020 10:48:50.234] [broadcastHubTest-akka.actor.default-dispatcher-3] [akka.stream.Log(akka://broadcastHubTest/system/StreamSupervisor-0)] [after broadcasting] Upstream finished.

10毫秒的油门效果

[DEBUG] [01/29/2020 10:56:26.030] [main] [EventStream(akka://broadcastHubTest)] logger log1-Logging$DefaultLogger started
[DEBUG] [01/29/2020 10:56:26.031] [main] [EventStream(akka://broadcastHubTest)] Default Loggers started
[DEBUG] [01/29/2020 10:56:26.136] [broadcastHubTest-akka.actor.default-dispatcher-2] [akka.stream.Log(akka://broadcastHubTest/system/StreamSupervisor-0)] [before broadcasting] Element: 1
[DEBUG] [01/29/2020 10:56:26.137] [broadcastHubTest-akka.actor.default-dispatcher-2] [akka.stream.Log(akka://broadcastHubTest/system/StreamSupervisor-0)] [before broadcasting] Element: 2
[DEBUG] [01/29/2020 10:56:26.137] [broadcastHubTest-akka.actor.default-dispatcher-2] [akka.stream.Log(akka://broadcastHubTest/system/StreamSupervisor-0)] [before broadcasting] Element: 3
[DEBUG] [01/29/2020 10:56:26.137] [broadcastHubTest-akka.actor.default-dispatcher-2] [akka.stream.Log(akka://broadcastHubTest/system/StreamSupervisor-0)] [before broadcasting] Upstream finished.
[DEBUG] [01/29/2020 10:56:26.139] [broadcastHubTest-akka.actor.default-dispatcher-5] [akka.stream.Log(akka://broadcastHubTest/system/StreamSupervisor-0)] [after broadcasting] Upstream finished.