my service is working with couchbase. when I want to update a document, first the service performs a lookup and gets the document with CAS, and then it updates the document. if the update failed with CASMismatch exception I want to perform retry with delay (retry when) on the lookUp (async request) and update. the problem is that retry invokes only the update observable and not the entire lookUp and update async requests.
this is retry code:
` public Func1<Observable<? extends Throwable>, Observable<?>> getRetryOnCASMismatchExceptionHandler(String unrecoverableErrorMessage) {
return observable -> observable
.zipWith(Observable.range(1, maxAttempts), ImmutablePair::of)
.flatMap(pair -> {
var throwable = pair.left;
var attemptsCounter = pair.right;
if (throwable instanceof CASMismatchException) {
// Retry code
return Observable.timer((long) attemptsCounter * backoffMs, TimeUnit.MILLISECONDS);
}
// Pass the throwable
return Observable.error(new RuntimeException(unrecoverableErrorMessage, throwable));
});
}`
the update code:
private Observable<String> updateDetectionWithRetry(DetectionFeed detectionFeed, String userId, String detectionPath)
{
updateDetection(detectionFeed, userId, detectionPath)
.retryWhen(retryHandlers.getRetryOnCASMismatchExceptionHandler("Failed to update persisted UserAccount with detection data [" + detectionFeed.toString() + "]"));
}
private Observable<String> updateDetection(DetectionFeed detectionFeed, String userId, String detectionPath)
{
return userRepo
.lookupDetection(userId, detectionPath)
.filter(existingDetection -> isNewDetectionFeed(existingDetection, detectionFeed))
.flatMap(detectionToPersist -> userRepo.replaceDetection(userId, detectionPath,
createDetectionToPersist(detectionFeed), detectionToPersist.getCas()))
}