确保将项目传递给RxJava中的onNext侦听器

时间:2014-11-29 01:22:31

标签: collections synchronization rx-java

我特别需要确保将物品交付给订户。如果onNext将返回boolean来表明该项目是否已被投放,那将会很不错,但不幸的是会返回void

我收集了由BlockingDeque支持的项目。新项目将添加到队列中并由订阅者汇集。订阅者可以随时取消订阅,该项目可能会丢失。这是我目前的实施方式:

return Observable.create((Subscriber<? super Item> subscriber) -> {
    while (true) {
        try {
            Item item = items.poll(poolTimeout, poolUnit);
            if (!subscriber.isUnsubscribed()) {
                subscriber.onNext(item);
            } else {
                items.addFirst(item);
                break;
            }
        } catch (InterruptedException e) {
            if (subscriber.isUnsubscribed()) {
                break;
            }
        }
    }
    subscriber.onCompleted();
}).subscribeOn(Schedulers.io())
   ...

即使我在致电isUnsubscribed之前检查onNext,但可能会出现Subscriber在支票和商品投放之间取消订阅的情况。它是常见的同步问题,并且很容易测试,例如,有时我的测试在检查收到的集合大小时失败了AssertionError

java.lang.AssertionError:
Expected size:<1000> but was:<999> in:

我正在寻找允许我以FIFO顺序交付物品的解决方案,100%确定没有物品丢失。任何想法如何在RxJava中实现这一点?

1 个答案:

答案 0 :(得分:1)

如果我正确理解您的问题,您需要一个有保证的端到端交付,并且可以选择捎带已取消订阅的被拒物品吗?

不幸的是,RxJava没有这种架构,因为许多运算符和类在取消订阅后只是简单地删除了下一个值。我也看到了一些问题:

  • 哪个订阅者可以判断该项目是否已成功使用?
  • boolean onNext(T t)在异步边界上的编写效果不佳。我们在取消订阅方面遇到了类似的问题。
  • 返回布尔值意味着如果下游使用observeOn,则需要阻止。

我只能想象一个有一组并发项目的设置。源将一个项放入此集并调用onNext。最终订户在成功处理该项目后,从该集合中删除该项目。如果此最终订户取消订阅,则可以将所有剩余项目视为未送达。但请注意,取消订阅是最好的,因此该集可能表示在取消订阅后短时间内成功传递的未传递事件,除非您同步onNext和取消订阅操作。 Here is an example code