每个项目回退超时(后退后没有完成)

时间:2015-10-14 20:00:41

标签: reactive-programming rx-java

如果我有来自某个来源的项目,我怎样才能在每个项目上设置超时以便能够用后备替换丢失的项目(这是前一项的功能),然后保持从原始源的流式传输?请注意,如果在回退后项目仍未到来,则应应用相同的超时策略(即从最新回退重新启动超时间隔)

现有的操作员超时(timeoutSelector,other)不合适,因为序列在后备(其他)之后终止。

尝试将源分割为窗口(1)然后在每个窗口上应用timeout()也不起作用,因为没有可用于提供timeoutSelector的先前项目。

有没有优雅的方法来做到这一点?

1 个答案:

答案 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