RxJava share()运算符:慢速订阅者会影响快速订阅者

时间:2018-04-03 12:05:08

标签: rx-java rx-java2

我在订阅者之间共享Flowable,这会慢慢消耗所发出的项目,而订阅者会快速消耗它们。

Flowable<Long> sharedFlowable =
            Flowable.generate(() -> 0L, (state, emitter) -> {
                emitter.onNext(state);
                return state + 1;
            })
            .share()
            .cast(Long.class);

    sharedFlowable
            .observeOn(computation())
            .subscribeWith(new PaceSubscriber<>("arthur", 1000, 1));

    sharedFlowable
            .observeOn(computation())
            .subscribeWith(new PaceSubscriber<>("ford", 1, 1));

基本上,PaceSubscriber执行Thread.sleep(.)。睡眠的持续时间是构造函数的第二个参数。第三个是订阅者通过调用请求方法request(.)

请求的元素数

我观察到的是以下现象:

  • 快速订阅者收到一定数量的项目
  • 然后,似乎是&#34;冻结&#34;等待
  • 收到一定数量商品的最慢订户
  • 等等。

例如,使用上面的代码,我得到了那种痕迹:

2018-04-03 13:39:44 [INFO ] [RxComputationThreadPool-2] INFO ford ⇶ received onNext(): 0
2018-04-03 13:39:44 [INFO ] [RxComputationThreadPool-2] INFO ford ⇶ received onNext(): 1
...
2018-04-03 13:39:44 [INFO ] [RxComputationThreadPool-2] INFO ford ⇶ received onNext(): 255
2018-04-03 13:39:47 [INFO ] [RxComputationThreadPool-3] INFO arthur ⇶ received onNext(): 130
2018-04-03 13:39:48 [INFO ] [RxComputationThreadPool-3] INFO arthur ⇶ received onNext(): 131
...
2018-04-03 13:41:21 [INFO ] [RxComputationThreadPool-3] INFO arthur ⇶ received onNext(): 224
2018-04-03 13:41:21 [INFO ] [RxComputationThreadPool-2] INFO ford ⇶ received onNext(): 257
2018-04-03 13:41:21 [INFO ] [RxComputationThreadPool-2] INFO ford ⇶ received onNext(): 258

实际上,我预计每个订阅者都会按照自己的节奏处理传入的项目,而不会在它们之间进行任何交互。特别是,我不会预期最慢的用户会减速最快。 我想知道这是一个问题还是预期的行为。我怀疑与observeOn()管理收到的项目队列以及与某些背压支持相关的事实有关的事情,但如果我能对此有一些有见地的解释,我会很高兴。

可以找到完整代码there

非常感谢提前!

1 个答案:

答案 0 :(得分:2)

  

实际上,我预计每个订阅者都会按照自己的节奏处理传入的项目而不需要它们之间的任何交互。

根据设计,这是publish share在引擎盖下使用的行为。消费者以锁步的方式进食,因此消费者不会因为消费中存在任何潜在的速度差异而无法进行多余的缓冲。

例如,您必须通过onBackpressureBuffer手动取消绑定较慢的流,但这可能会导致内存使用过多。

这种行为是由于背压效应(最慢的路径还没有准备好接收物品),部分是为了在复杂的定时情况下避免数据损失。