Rx使用限制+超时缓冲快速生成流

时间:2016-09-09 15:43:24

标签: rx-java

我正在尝试通过在适当的时候执行批处理请求来优化使用RxJava的Web服务调用,但不会给响应带来太多延迟。 为此,我使用buffer(closingSelector)运算符和debounce()作为结束选择器,如下所示:

Observable<BaseCall<T, R>> burstyMulticast = requestStream.share();
Observable<BaseCall<T, R>> burstyDeBounced = burstyMulticast.debounce(windowSize, windowUnit);
burstyMulticast.buffer(burstyDeBounced).subscribe(/* call external WS with batches */);

它运行正常,但如果requestStream生成得太快,它会发出大批量,对于WS来说太大了,所以我想以某种方式限制批量大小。 所以我需要一个closingSelector,如果缓冲区中有X个项目,或者自上一个项目从上游到达时Y时间过去,则会发出一个关闭事件。

除了实现类似于Operator的自定义OperatorDebounceWithTime之外,我似乎找不到一个好的解决方案,但是内部缓冲区返回缓冲区中的所有元素而不是最后一个元素。

是否有更简单的方法来实现这一目标,例如通过结合一些操作?

修改

发布问题后,我意识到上面的代码片段还有另一个问题:如果请求的流量持续快于去抖动超时(requestStream产生的速度超过windowSize),那么burstyDeBounced赢了“ t发出任何内容,以便缓冲所有请求,直到传入流中有足够长的暂停。

2 个答案:

答案 0 :(得分:0)

您可以将去抖动源的大缓冲区拆分为较小的缓冲区:

Observable<BaseCall<T, R>> burstyMulticast = requestStream.share();
Observable<BaseCall<T, R>> burstyDeBounced = burstyMulticast
    .debounce(windowSize, windowUnit);

burstyMulticast.buffer(burstyDeBounced)
.onBackpressureBuffer()
.concatMapIterable(list -> Lists.partition(list, windowSizeLimit))
.subscribe(...);

其中Lists.partition来自Google Guava。

答案 1 :(得分:0)

我最终实现了一个自定义操作:https://gist.github.com/zsoltm/79462b37c0943b4fbef2ee3968155f27它似乎运行良好。我很乐意接受改进建议。