RxJava:重试时有重试限制

时间:2015-01-20 08:22:51

标签: couchbase rx-java

我是ReactiveX和反应式编程的新手。我需要为Couchbase CAS操作实现重试机制,但Couchbase网站上的示例显示重试时,它似乎无限期地重试。我需要在那里的某个地方有一个重试限制和重试计数。

简单的retry()可以工作,因为它接受retryLimit,但我不希望它只在CASMismatchException上重试每个异常。

有什么想法吗?我正在使用RxJava库。

3 个答案:

答案 0 :(得分:8)

除了Simon Basle所说的,这是一个带线性退避的快速版本:

.retryWhen(notification ->
    notification
    .zipWith(Observable.range(1, 5), Tuple::create)
    .flatMap(att ->
            att.value2() == 3 ? Observable.error(att.value1()) : Observable.timer(att.value2(), TimeUnit.SECONDS)
    )
)

请注意" att"这是一个由throwable和重试次数组成的元组,因此你可以非常具体地实现基于这两个参数的返回逻辑。

如果您想了解更多信息,可以查看我目前正在撰写的有弹性的文档:https://gist.github.com/daschl/db9fcc9d2b932115b679#retry-with-delay

答案 1 :(得分:2)

重试当显然比简单的重试更复杂一点,但这里是它的要点:

  • 您传递notificationHandler功能进行重试时需要Observable<Throwable>并输出Observable<?>
  • 此返回的Observable的发射确定何时应该重试或停止
  • 因此,对于原始流中每个发生的异常,如果处理程序的一个发出1个项目,那么将重试1次。如果它发出2个项目,则会有2个......
  • 一旦处理程序的流发出错误,就会中止重试。

使用它,您可以:

  • 仅适用于CasMismatchExceptions:只是让您的函数在其他情况下返回Observable.error(t)
  • 仅重试特定次数:对于每个异常,来自Observable.range的flatMap表示最大重试次数,如果需要增加延迟,则使用重试#返回Observable.timer

您的用例与RxJava doc here

中的用例非常接近

答案 2 :(得分:2)

恢复此线程,因为在Couchbase Java SDK 2.1.2中有一种新的更简单的方法:使用RetryBuilder

Observable<Something> retryingObservable =
sourceObservable.retryWhen(
  RetryBuilder
    //will limit to the relevant exception
    .anyOf(CASMismatchException.class)
    //will retry only 5 times
    .max(5)
    //delay doubling each time, from 100ms to 2s
    .delay(Delay.linear(TimeUnit.MILLISECONDS, 2000, 100, 2.0))
  .build()
);