首先,从大的方面说,这篇文档的名字,虽然叫“Backpressure”(背压),但却是在讲述一个更大的话题,“Flow Control”(流控)。Backpressure只是解决Flow Control的其中一个方案。 就像小学做的那道数学题:一个水池,有一个进水管和一个出水管。如果进水管水流更大,过一段时间水池就会满(溢出)。这就是没有Flow Control导致的结果。 而解决Flow Control有几种思路呢? 举个例子比较一下(1)和(4)。(4)相当于很多车行驶在盘山公路上,而公路只有一条车道。那么排在最前面的第一辆车就挡住了整条路,后面的车也只能排在后面。而(1)相当于银行办业务时的窗口叫号,窗口主动叫某个号过去(相当于请求),那个人才过去办理。 然后,从细的方面解释一下sample,throttleFirst,debounce。以及onBackpressureBuffer,onBackpressureDrop,onBackpressureBlock和ConnectableObservable(multicast)。 sample就是throttleLast,采样。类比一下音频采样,8kHz的音频就是每125微秒采一个值。sample可以配置成,比如每100毫秒采样一个值,但100毫秒内上游可能过来很多值,选那个值呢,就是选最后那个值。所以它也叫throttleLast。 throttleFirst跟sample类似,比如还是每100毫秒采样一个值,但选这100毫秒内的第一个值。 debounce,也叫throttleWithTimeout,名字里就包含一个例子。比如,一个网络程序维护一个TCP连接,不停地收发数据,但中间没数据可以收发的时候,就有间歇。这段间歇的时间,可以称为idle time。当idle time超过一个预设值的时候,就算超时了(timeout),这个时候可能就需要把连接断开了。实际上一些做server端的网络程序就是这么工作的。每收发一个数据包之后,启动一个计时器,等待idle time过去之后的超时,如果计时器到时之前,又有收发数据包的行为,那么计时器重置,等待一个新的idle time。当计时器到时了,就time out了,这个连接就可以关闭了。debounce的行为,跟这个非常类似,可以用它来找到连续的收发事件之后idle time超时后的timeout事件。 最后还有一个新的问题需要说明。Backpressure有些Observable是支持的,有些不支持。但它们可以通过operator来转化。 onBackpressureBuffer,onBackpressureDrop,onBackpressureBlock就可以把一个不支持Backpressure的Observable转成一个支持Backpressure的Observable(即支持request请求)。但转完之后的策略不太相同。 onBackpressureBuffer是不丢弃数据的处理方式。把上游收到的全部缓存下来,等下游来请求再发给下游。相当于一个水库。但上游太快,就会buffer溢出。 onBackpressureDrop就是当上游来数据的时候,看下游有没有需求,有需求就发给下游,否则上游来的数据就丢掉。 onBackpressureBlock也是看下游有没有需求,下游没有需求,不丢弃,但试图堵住上游的入口(能不能真堵得住还得看上游的情况了),自己并不缓存。 相反,有时候一些operator也能把一个支持Backpressure的Observable变成一个不支持Backpressure的Observable。比如,ConnectableObservable就是这样。它类似于把一条河的主干,在下游分成若干支流(但不太一样的是每条支流的水量都跟主干一样,是拷贝的)。那么很好理解,下游某个支流想对上游产生背压,是不太可能的,它阻止不了水流流向其它支流。 |
|
来自: Ricky_图书馆 > 《无线/网络/通信接口/协议》