通过热观察避免背压

时间:2015-10-16 18:27:51

标签: android geolocation rx-java backpressure

我正在使用Android ReactiveLocation library来接收定期更新。我希望继续接收位置更新,即使我的应用程序中没有任何内容正在使用它们,因此我总是有一个最新的位置,如果需要,我可以立即使用。

这就是我开始在应用的核心组件中获取位置更新的方法。我想将最新的值以及任何新检测到的位置重新发布到我应用中链接下游的任何订阅者,这就是replay(1)的用途。

locationProvider = new ReactiveLocationProvider(context);
locationObservable = locationProvider.getUpdatedLocation(locationRequest)
.replay(1);

在应用程序的其他地方,我订阅了这个重新发布的obervable:

locationSubscription = locationObservable
        .filter(new Func1<Location, Boolean>() {
            @Override
            public Boolean call(Location location) {
                return location.getAccuracy() < LOCATION_ACCURACY_THRESHOLD;
            }
        })
        .subscribe(new Action1<Location>() {
            @Override
            public void call(Location location) {
            }
        });

这似乎可以完成这项任务:我的最终用户获得了立即返回的最新位置,并继续接收新的更新,但我想确保我没有在链中某处建立一个巨大的未使用位置缓冲区最终订户未订阅。我是一个Rx菜鸟。背压如何适用于这种情况? replay(1)正在做我期望的事情,除了最新的地点之外还丢弃所有不需要的地点吗?

1 个答案:

答案 0 :(得分:1)

重播有几个因素可以发挥作用。 replay(1)执行背压协调并根据订户的请求重放值。

这意味着如果订阅者位于异步边界后面,replay将开始累积值。发生这种情况的速率取决于当前的订户组:运营商请求订户请求的最大数量,因此如果有限和无限订户混合使用,如果他们以不同的速率消费,则可能导致缓冲膨胀。

您可以将其缓冲区视为单个链接列表,其中每个订阅者指向该列表中的节点以及指向列表末尾之前的运算符。由于单个链接,如果没有订阅者,列表的前面可以被垃圾收集。

如果有大量请求者取消订阅,replay()将&#34; drop&#34;多余的值,并一次持续保持1个元素,慢慢地&#34;滴掉&#34;。

另一种方法是使用BehaviorSubject来记住最后一个值,并且根本不做背压,因此没有缓冲膨胀的风险,但有MissingBackpressureException的风险。

修改

实际上,我认为重播()中存在背压错误,因此冷源可能无法正常工作。