如何播放冷观察:用背压重播?

时间:2017-03-05 16:59:57

标签: scala reactive-programming akka-stream rx-java2 monix

我实际上正在使用Scala,但这个问题对所有Rx和流式框架都是通用的。

我的用例是我有一个生成的observable(因此很冷),我希望多个消费者并行使用完全相同的值,但我希望它们的吞吐量有很大差异。

我需要通过广播带有重放的observable来完成,但我发现使用最大缓冲区大小重放的常见策略是在溢出时从缓冲区中删除元素(然后为最慢的消费者丢失)对生产者施加压力如果你把所有广播的可观测量视为热点,那就没有意义了,但就我而言,我知道它实际上是冷的并且可能会受到压力。

是否有某种方法可以在任何JVM反应流兼容框架中实现这一目标?

非常感谢!

1 个答案:

答案 0 :(得分:1)

RxJava通过publish运算符支持这一点,该运算符协调来自各个消费者的请求,也就是说,它以与最慢的消费者请求一样快的速率请求。不幸的是,目前没有RxScala 2,只有RxJava 2支持Reactive-Streams规范,因此,您可能会有一些不便将其变成Scala:

Flowable.fromPublisher(Flowable.range(1, 1000))
.publish(f -> 
    Flowable.mergeArray(
        f.observeOn(Schedulers.computation()).map(v -> v * v),
        f.observeOn(Schedulers.computation()).map(v -> v * v * v)
    )
 )
 .blockingSubscribe(System.out::println);

另一种方法是使用ConnectableObservable并在所有消费者订阅后手动连接:

ConnectableFlowable<Integer> co = Flowable.fromPublisher(Flowable.range(1, 1000))
    .publish();

co.observeOn(Schedulers.computation()).map(v -> v * v)
  .subscribe(System.out::println);

co.connect();