如果我有来自某个来源的项目,我怎样才能在每个项目上设置超时以便能够用后备替换丢失的项目(这是前一项的功能),然后保持从原始源的流式传输?请注意,如果在回退后项目仍未到来,则应应用相同的超时策略(即从最新回退重新启动超时间隔)
现有的操作员超时(timeoutSelector,other)不合适,因为序列在后备(其他)之后终止。
尝试将源分割为窗口(1)然后在每个窗口上应用timeout()也不起作用,因为没有可用于提供timeoutSelector的先前项目。
有没有优雅的方法来做到这一点?
答案 0 :(得分:1)
您可以通过publish(Func1)
技巧实现此目的:
TestScheduler s = Schedulers.test();
Scheduler.Worker w = s.createWorker();
PublishSubject<Long> source = PublishSubject.<Long>create();
PublishSubject<Long> other = PublishSubject.create();
source
.publish(o -> {
AtomicReference<Long> last = new AtomicReference<>();
return o
.doOnNext(last::set)
.doOnCompleted(() -> other.onCompleted())
.timeout(75, TimeUnit.MILLISECONDS, s)
.doOnError(e -> {
if (last.get() != null) {
other.onNext(- last.get());
}
})
.retry();
}
).mergeWith(other)
.forEach(System.out::println);
w.schedule(() -> source.onNext(1L), 0, TimeUnit.MILLISECONDS);
w.schedule(() -> source.onNext(2L), 50, TimeUnit.MILLISECONDS);
w.schedule(() -> source.onNext(3L), 150, TimeUnit.MILLISECONDS);
w.schedule(() -> source.onNext(4L), 200, TimeUnit.MILLISECONDS);
w.schedule(() -> source.onNext(5L), 500, TimeUnit.MILLISECONDS);
w.schedule(() -> source.onNext(6L), 550, TimeUnit.MILLISECONDS);
s.advanceTimeBy(1, TimeUnit.SECONDS);
您可能需要在onBackpressureXXX
之前和publish
之内应用mergeWith
。