我正在使用Rx-ified API for vertx,这个问题必须做一个潜在的无限重试 - 直到成功循环我想实现但是有困难。我是RxJava的新手。
以下是我想做的事情:
我遇到的第一个问题是如何完成第2步。
如果您熟悉vert.x Rx api,这就是在上面的步骤1)中发出请求的意思:
vertx.eventBus().<JsonObject>sendObservable( "theAddress", aJsonObject );
上面的代码返回一个Observable实例,该实例将发出响应或错误(例如,如果存在超时)。 Observable永远不会再发出任何东西(或者每次订阅时它总会发出完全相同的东西,我不知道哪个)。
vertx.eventBus().<JsonObject>sendObservable( "theAddress", aJsonObject )
.retry()
我认为为了发出重试,我可以使用RxJava的retry()运算符,我尝试过,但由于源可观察的性质,这样做完全没有任何有用的效果。没有新的请求消息被发送,因为唯一的事情是&#34;重试&#34;是对原始源的订阅,它永远不会发出任何不同的内容。
vertx.eventBus().<JsonObject>sendObservable( "theAddress", aJsonObject )
.retryWhen( error -> {
return _vertx.eventBus().<JsonObject>sendObservable( "theAddress", aJsonObject )
})
然后我想我可以使用RxJava的retryWhen()运算符,这允许我在根observable发出错误时发出第二个observable。我想,第二个可观测量可能与上面第一步产生初始观察者的代码相同。
但是,retryWhen()运算符(see documentation)不允许第二个observable发出错误,而不会以错误结束订阅。
因此,我无法确定如何在此链的第一部分内设置可能无限的重试循环。
我必须在这里遗漏一些东西,但我无法确定它是什么。
vertx.eventBus().<JsonObject>sendObservable( "theAddress", aJsonObject )
// imagine that retryWhen() accomplishes an infinite retry
.retryWhen( error -> {
return _vertx.eventBus().<JsonObject>sendObservable( ... )
})
.flatMap( response -> {
// inspect response, if it has usable data,
// return that data as an observable
return Observable.from(response.data());
// if the response has no usable data,
// wait for some time, then start the whole process
// all over again
return Observable.timer(timeToWait).<WHAT GOES HERE?>;
})
第二个问题是如何实现第3步。这在我看来就像是第一个问题,只是难以理解,因为我不需要重试直接源可观察,我需要等待一个比特,然后在步骤1)重新开始。
无论我创建什么Observable似乎都需要链中的所有元素导致这一点,这似乎是一种应该避免的递归。
此时,我们非常欢迎任何帮助或建议。
答案 0 :(得分:4)
非常感谢Ben Christensen在RxJava Google Group上指出了defer()运算符,它将在每个订阅上生成一个新的Observable。然后可以使用标准的retry()运算符来组合,以获得无限的重试。
所以,在我的问题中第一个问题的最简单的解决方案是这样的:
Observable.defer( () -> vertx.eventBus().<JsonObject>sendObservable( "theAddress", aJsonObject ) )
.retry()
...如果需要指数退避,您可以在给予defer()运算符的工厂方法中添加带有适当参数的Observable.timer()。
我仍然在研究第二个问题。