Ретривер гуавы, который вызывает функцию, пока не произойдет исключение - PullRequest
0 голосов
/ 14 января 2019

Скажите, у меня есть такой код:

public void deleteResource(UUID resourceId) {
    deleteFromDb();
    deleteFromALotOfOtherPlaces();    // Takes a long time!
}

public DescribeResourceResult describeResource(UUID resourceId) throws ResourceNotFoundException {
    return getResourceDescription(resourceId);
}

К сожалению, удаление не означает, что оно завершено. Единственный способ убедиться, что удаление завершено, - вызвать describeResource, который выдаст исключение, если ресурс был удален.

Я хочу написать ретритер, который будет неоднократно вызывать describeResrouce, пока не произойдет ResourceNotFoundException. Как я могу это сделать?

Вот что у меня есть:

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));

Спасибо!

Ответы [ 2 ]

0 голосов
/ 23 января 2019

Использование Отказоустойчивость :

RetryPolicy<Object> retryPolicy = new RetryPolicy<>()
  .abortOn(ResourceNotFoundException.class);
  .withDelay(Duration.ofMillis(500))
  .withMaxDuration(Duration.ofSeconds(10)); 

Failsafe.with(retryPolicy).get(() -> getResourceDescription(resourceId));
0 голосов
/ 14 января 2019

Я не очень знаком с Guava Retryer, поэтому после непродолжительного исследования я не смог найти готовый к использованию StopStrategy, поэтому мой совет - реализовать его самостоятельно

static class OnResourceNotFoundExceptionStopStrategy implements StopStrategy {

    @Override
    public boolean shouldStop(Attempt attempt) {
        if (attempt.hasException() 
                     && attempt.getExceptionCause() instanceof ResourceNotFoundException) {
            return true;
        }
        return false;
    }

}

При этой стратегии повторные попытки прекратятся, когда вы поймаете ResourceNotFoundException. После этого исправьте типы и правильно определите Retryer

final Retryer<DescribeResourceResult> deleteResourceRetryer = RetryerBuilder
            .<DescribeResourceResult>newBuilder()
            .retryIfResult(Predicates.notNull())
            .withWaitStrategy(WaitStrategies.fixedWait(500, TimeUnit.MILLISECONDS))
            .withStopStrategy(new OnResourceNotFoundExceptionStopStrategy())
            .build();

И наконец, начните повторную попытку

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
}

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...