PublishProcessor.offer()如何知道下游没有消耗先前的发射?

时间:2019-12-19 07:15:53

标签: rx-java rx-java2

我使用PublishProcessor.offer()从上游发出。我读到(*),如果订户不准备接收下一个事件,则它可能返回false,因为PublishProcessor不协调背压。我想知道它是如何工作的。 PublishProcessor如何知道订阅者尚未准备好?

我读到上游可能知道下游通过反作用拉动处理排放物的潜力:

someObservable.subscribe(new Subscriber<t>() {
    @Override
    public void onStart() {
      request(1);
    }

    @Override
    public void onCompleted() {
      // gracefully handle sequence-complete
    }

    @Override
    public void onError(Throwable e) {
      // gracefully handle error
    }

    @Override
    public void onNext(t n) {
      // do something with the emitted item "n"
      // request another item:
      request(1);
    }
});

https://github.com/ReactiveX/RxJava/wiki/Backpressure

但是我的订阅看起来像这样:

publishProcessor.subscribe(new Consumer<T>() {
                @Override
                public void accept(T t) throws Exception {
                    // do IO
                }
            }, Log::submitCrash);

是否在内部调用request(1); accept()完成之后,还是不执行反应式拉动?我试图阅读代码,但事实并非如此。该消费者将传递给LambdaSubscriber。而且LambdaSubscriber.onNext()不会调用request(n)。

此订阅方法的javadoc:

 public final Disposable subscribe(Consumer<? super T> onNext, Consumer<? super Throwable> onError) 

说:运营商以无限制的方式使用了源{@code Publisher}(即,否  施加反压)。

因此,它对反应性拉力没有任何说明。以无界方式使用源是否意味着将无界背压缓冲区应用于此订阅,或者根本没有背压缓冲区?

PublishProcessor是否还有其他机制可以知道订阅者是否已完成对发射值的消耗?

(*)

  

PublishProcessor既是Flowable也是FlowableProcessor,   但是,它不能协调不同   订户以及上游源和订户之间。如果   如果没有订阅者,则通过onNext(Object)接收上游项   准备接收商品时,该订户将通过   MissingBackpressureException。为了避免这种情况,请使用offer(Object)   如果返回false,请稍后再试。

http://reactivex.io/RxJava/javadoc/io/reactivex/processors/PublishProcessor.html

1 个答案:

答案 0 :(得分:0)

每个Subscriber都会收到一个特殊的Subscription,该记录跟踪消费者发出的request金额,如果PublishProcessor可以致电{{1 }}放在onNext上。

如果消费者跟踪了decrements并选中了is zero,则认为该消费者尚未准备就绪。

如果您同步消费Subscriber并从PublishProcessor发出request,则跟踪量将始终大于零,因此onNext可以通过。

但是,如果您异步使用(例如,通过应用offer),则处理器和您的使用者之间现在有一个有限的缓冲区可能会填满,并且跟踪的请求量最终可能为零,从而防止了{ {1}}发出更多信号。

无限制消费意味着消费者发出observeOn,这被解释为消费者准备接收任何数量的物品。如果您将offer订阅了另一个request(Long.MAX_VALUE),则PublishProcessor本身也会inside offer

通常,无界并不意味着无限的缓冲,因为特定的使用者可能会在Publisher的调用者线程上同步丢弃,批处理,采样或处理项目,因此不会发生溢出。