如何用RxJava实现一个大小取决于消费者和生产者速度的缓冲区?

时间:2018-05-24 11:06:23

标签: rx-java rx-java2

要求如下:

  1. 当生产者比消费者更快时,生产的物品应该被缓冲,直到缓冲器满了。当缓冲区已满时,不再要求生产者生产新的物品(背压)。
  2. 当消费者比生产者更快时,发出缓冲的物品以进行补偿。如果缓冲区变空,那么就会出现饥饿现象,但在这种情况下我们无能为力。
  3. 缓冲的目标是减少饥饿的风险;因此,只要生产者比消费者更快,它就应该保持饱满。
  4. 我尝试过不同的可流动操作符。非常接近这些要求的是带有缓冲区大小的observeOn。但是这个算子背后有一些魔力:当缓冲区已满时,它会逐渐清空,直到它的大小低于其总容量的25%,并且在此过程中不会向生产者请求任何项目。

    我应该使用哪个运营商或运营商组合来满足这些要求?

    提前致谢。

2 个答案:

答案 0 :(得分:0)

使用多个rebatchRequests(在封面下使用observeOn)来人为地提高进一步请求的级别。

答案 1 :(得分:0)

我终于得出结论,自定义可流动操作符可以是管理溢出(通过背压)和下溢(通过实际上充当元素库以避免饥饿的缓冲区)的可接受解决方案。

当此操作符连接到可流动管道时,元素库将填充生产者发出的元素。消费者根据需要获取储存在储存库中的元素。生产者和消费者在两个不同的调度程序上运行。

溢出情况:

  • 当水库充满时,不再要求生产者排放 新元素(由于管道的背压设施)。

下溢情况:

  • 根据需要,水库用于向消费者提供元素。

生命周期

  • 缓冲阶段:储液器充满,直至充满。在此阶段,消费者不会收到任何元素。
  • 转移阶段:消费者在需要时获取储存在储存库中的元素;只要产量不足,生产者就会在水库中存储元素。
  • 冲洗阶段:生产者已完成;消费者获取储存库中剩余的所有元素,最后收到一个完整的信号。

此操作符在溢出和下溢情况下都是非阻塞的。

<强>用法:

ReservoirOperator op = new ReservoirOperator(bufferSize, Schedulers.io());
upstream.lift(op).subscribe(consumer);