RxJava / RxScala背压使用请求

时间:2016-01-15 18:04:21

标签: reactive-programming rx-java rx-scala

我在使用RxJava背压时遇到了问题。基本上,我有一个生成器,它生成的项目多于消费者可以处理的项目,并希望有一些缓冲队列来处理我可以处理的项目,并在我完成其中一些项目时请求,例如:

object Tester extends App {

Observable[Int] { subscriber =>
  (1 to 100).foreach { e =>
    subscriber.onNext(e)
    Thread.sleep(100)
    println("produced " + e + "(" + Thread.currentThread().getName + Thread.currentThread().getId + ")")
  }
}
.subscribeOn(NewThreadScheduler())
.observeOn(ComputationScheduler())
.subscribe(
  new Subscriber[Int]() {
    override def onStart(): Unit = {
      request(2)
    }

    override def onNext(value: Int): Unit = {
      Thread.sleep(1000)
      println("consumed " + value + "(" + Thread.currentThread().getName + Thread.currentThread().getId + ")")
      request(1)
    }

    override def onCompleted(): Unit = {
      println("finished ")
    }
})

Thread.sleep(100000)

我希望获得像

这样的输出
produced 1(RxNewThreadScheduler-113)
consumed 1(RxComputationThreadPool-312)
produced 2(RxNewThreadScheduler-113)
consumed 2(RxComputationThreadPool-312)
produced 3(RxNewThreadScheduler-113)
consumed 3(RxComputationThreadPool-312)
......

但相反,我得到了

produced 1(RxNewThreadScheduler-113)
produced 2(RxNewThreadScheduler-113)
produced 3(RxNewThreadScheduler-113)
produced 4(RxNewThreadScheduler-113)
produced 5(RxNewThreadScheduler-113)
produced 6(RxNewThreadScheduler-113)
produced 7(RxNewThreadScheduler-113)
produced 8(RxNewThreadScheduler-113)
produced 9(RxNewThreadScheduler-113)
consumed 1(RxComputationThreadPool-312)
produced 10(RxNewThreadScheduler-113)
produced 11(RxNewThreadScheduler-113)
produced 12(RxNewThreadScheduler-113)
produced 13(RxNewThreadScheduler-113)
.....

1 个答案:

答案 0 :(得分:1)

使用Observable实施Observable.create时,您需要管理背压(这不是一项简单的任务)。在这里,你的observable只是忽略了被动拉取请求(你只是迭代,而不是等待请求调用迭代器的next()方法)。

如果可能,尝试使用Observable工厂方法,例如range等...并使用map / flatMap进行撰写,以获得所需的源Observable,会尊重背压。

否则,请查看最近介绍的实验性实用程序类,以便在OnSubscribe实施中正确管理背压:AsyncOnSubscribeSyncOnSubscribe

这是一个非常天真的例子:

Observable<Integer> backpressuredObservable = 
  Observable.create(SyncOnSubscribe.createStateful(
    () -> 0, //starts the state at 0
    (state, obs) -> {
        int i = state++; //first i is 1 as desired
        obs.next(i);
        if (i == 100) { //maximum is 100, stop there
            obs.onCompleted();
        }
        return i; //update the state
}));