Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rx java MissingBackpressureException:由于缺少请求,无法发出缓冲区_Rx Java - Fatal编程技术网

Rx java MissingBackpressureException:由于缺少请求,无法发出缓冲区

Rx java MissingBackpressureException:由于缺少请求,无法发出缓冲区,rx-java,Rx Java,我收到了一份错误报告,其中包括MissingBackpressureException:由于缺少RxJava可流动的请求,因此无法发出缓冲区,但我正在努力创建一个简单的测试用例来演示问题(维护可流动的结构) 这是我试图组合的测试,它在管道中保持相同的阶段: int inputEvents=10000; CountDownLatch completed = new CountDownLatch(1); Flowable<List<String>> flowable = F

我收到了一份错误报告,其中包括
MissingBackpressureException:由于缺少RxJava
可流动
的请求
,因此无法发出缓冲区,但我正在努力创建一个简单的测试用例来演示问题(维护
可流动
的结构)

这是我试图组合的测试,它在管道中保持相同的阶段:

int inputEvents=10000;

CountDownLatch completed = new CountDownLatch(1);
Flowable<List<String>> flowable = Flowable.<String>create(e -> {

    System.out.println(Thread.currentThread().getName() + ": Will send");
    for (int counter = 0; counter < inputEvents; counter++) {
        e.onNext("" + counter);
        Thread.sleep(5);
    }
    System.out.println(Thread.currentThread().getName() + ": Completed sending");
    e.onComplete();
}, BackpressureStrategy.DROP)
    .onBackpressureDrop(s -> System.out.println("Backpressure, dropping " + Arrays.asList(s)))
    .buffer(1, TimeUnit.SECONDS)
    .doOnNext(strings -> System.out.println("\t" + Thread.currentThread().getName() + ": Buffered: " + strings.size() + " items"))
    .observeOn(Schedulers.io(), false)
    .doOnNext(strings -> {
        System.out.println("\t" + "\t" + Thread.currentThread().getName() + ": Waiting: " + strings.size());
        Thread.sleep(5000);
    });

flowable
    .subscribe(s -> System.out.println("\t" + "\t" + "onNext: " + s.size()),
            error -> {
                throw new RuntimeException(error);
            },
            () -> {
                System.out.println("\t" + "\t" + "Complete");
                completed.countDown();
            });

completed.await();

所以我认为这与缓冲区的下游工作有关

但是,无论我在
doOnNext
中阻塞多长时间,我都无法重现该问题。示例输出:

main: Will send
    RxComputationThreadPool-1: Buffered: 197 items
        RxCachedThreadScheduler-1: Waiting: 197
    RxComputationThreadPool-1: Buffered: 196 items
    RxComputationThreadPool-1: Buffered: 197 items
    RxComputationThreadPool-1: Buffered: 197 items
    RxComputationThreadPool-1: Buffered: 196 items
    RxComputationThreadPool-1: Buffered: 197 items
        onNext: 197
        RxCachedThreadScheduler-1: Waiting: 196
    RxComputationThreadPool-1: Buffered: 197 items
    RxComputationThreadPool-1: Buffered: 197 items
    RxComputationThreadPool-1: Buffered: 196 items
    RxComputationThreadPool-1: Buffered: 197 items
    RxComputationThreadPool-1: Buffered: 197 items
        onNext: 196
        RxCachedThreadScheduler-1: Waiting: 197
    RxComputationThreadPool-1: Buffered: 197 items
    RxComputationThreadPool-1: Buffered: 197 items
...

我期待着,因为
线程.sleep(5000)
需要很长时间,我们会得到反压力


理想情况下,在使用TestScheduler/TestSubscriber的测试中,是否有一种方法可以模拟这种情况(以避免
Thread.sleep()
s)?

我能够通过增加事件的发射速率、增加最大事件数来重现MissingBackpressureException,以及降低消费者处理它们的速度

溢出的缓冲区是默认的
observeOn(…)
操作员缓冲区,大小为128。由于它每秒接收一次新列表,因此至少需要几分钟的背压才能溢出

注意,您可以通过将此默认缓冲区大小作为参数传递给
observeOn(…)
来覆盖它

回到背压处理,我认为管道的主要问题是
缓冲区(1,TimeUnit.SECONDS)
操作符。如果您查看javadoc:

背压:此操作员在使用时不支持背压 时间它向上游请求Long.MAX_值,而不服从下游 请求

由于上述原因,
onBackPressureDrop(…)
永远不会被调用。我认为您可以通过将
置于backpressuredrop(…)
之后的
缓冲区(…)
来解决此问题。这样做会导致您的
背压,掉落…
消息

您应该能够使用以下方法对此进行单元测试:
TestScheduler.advanceTimeBy(长,时间单位)
。尽管我不得不承认,我还没有试过。

谢谢你看。我很困惑-有多个
缓冲区:197个项目
日志表明一次有197个项目被传递到
observeOn
-鉴于下游操作需要几秒钟才能发生,这难道不应该溢出
observeOn
中的缓冲区吗?从生产到本测试,我观察到的另一个区别是尽管两者都使用
Schedulers.io()
,但在生产过程中创建了多个线程(其中128个,我猜是模仿上游缓冲区的onNexts),而每当我运行此测试时,只创建一个线程。@DanGravell,
observeOn
的上游正在发出
列表
,因此,缓冲区实际上是128个
列表的缓冲区,而不是单个
字符串的缓冲区。噢,我的粒度搞错了!谢谢,我会再看看这个。是的,只是通过改变参数,这可以工作,我对代码太温和了!
main: Will send
    RxComputationThreadPool-1: Buffered: 197 items
        RxCachedThreadScheduler-1: Waiting: 197
    RxComputationThreadPool-1: Buffered: 196 items
    RxComputationThreadPool-1: Buffered: 197 items
    RxComputationThreadPool-1: Buffered: 197 items
    RxComputationThreadPool-1: Buffered: 196 items
    RxComputationThreadPool-1: Buffered: 197 items
        onNext: 197
        RxCachedThreadScheduler-1: Waiting: 196
    RxComputationThreadPool-1: Buffered: 197 items
    RxComputationThreadPool-1: Buffered: 197 items
    RxComputationThreadPool-1: Buffered: 196 items
    RxComputationThreadPool-1: Buffered: 197 items
    RxComputationThreadPool-1: Buffered: 197 items
        onNext: 196
        RxCachedThreadScheduler-1: Waiting: 197
    RxComputationThreadPool-1: Buffered: 197 items
    RxComputationThreadPool-1: Buffered: 197 items
...