我使用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
答案 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
的调用者线程上同步丢弃,批处理,采样或处理项目,因此不会发生溢出。