Reputation: 192
Say I have some code like this:
public void deleteResource(UUID resourceId) {
deleteFromDb();
deleteFromALotOfOtherPlaces(); // Takes a long time!
}
public DescribeResourceResult describeResource(UUID resourceId) throws ResourceNotFoundException {
return getResourceDescription(resourceId);
}
Unfortunately, the delete doesn't signal that it's completed. The only way to verify that the deletion has completed is to call describeResource
which will throw an exception if the resource has been deleted.
I want to write a retryer that will repeatedly call describeResrouce
until a ResourceNotFoundException
occurs. How can I do that?
Here's what I have so far:
final Retryer<ResourceNotFoundException> deleteResourceRetryer = RetryerBuilder.<ResourceNotFoundException>newBuilder()
.withWaitStrategy(WaitStrategies.fixedWait(500, TimeUnit.MILLISECONDS))
.withStopStrategy(StopStrategies.stopAfterDelay(10, TimeUnit.SECONDS))
.build();
// Error: Bad return type in lambda expression: DescribeResourceResult cannot be converted to ResourceNotFoundException
deleteResourceRetryer.call(() -> describeResource(resourceId));
Thank you!
Upvotes: 0
Views: 1871
Reputation: 1885
I not so familar with Guava's Retryer
, thus after short investigation I was not able to find ready-to-use StopStrategy
, so my advice is to implement it yourself
static class OnResourceNotFoundExceptionStopStrategy implements StopStrategy {
@Override
public boolean shouldStop(Attempt attempt) {
if (attempt.hasException()
&& attempt.getExceptionCause() instanceof ResourceNotFoundException) {
return true;
}
return false;
}
}
With that strategy retries will stop when you'll catch ResourceNotFoundException
. After that fix types and correctly define Retryer
final Retryer<DescribeResourceResult> deleteResourceRetryer = RetryerBuilder
.<DescribeResourceResult>newBuilder()
.retryIfResult(Predicates.notNull())
.withWaitStrategy(WaitStrategies.fixedWait(500, TimeUnit.MILLISECONDS))
.withStopStrategy(new OnResourceNotFoundExceptionStopStrategy())
.build();
And finally, start retrying
try {
deleteResourceRetryer.call(() -> describeResource(resourceId));
} catch (ExecutionException e) {
// should not happens, because you will retry if any exception rather
// than ResourceNotFoundException raised in your describeResource method
} catch (RetryException e) {
// should not happens, because my implementation of StopStrategy
// (as it looks in this example) is effectively infinite, until target exception.
// For sure you're free to override it to anything you want
}
Hope it helps!
Upvotes: 1