根据结果重试方法(而不是异常)
2022-09-04 03:39:31
我有一个具有以下签名的方法:
public Optional<String> doSomething() {
...
}
如果我得到一个空,我想重试此方法,只有在3次后返回空。Optional
Optional
我查看并找到了弹簧注释,但它似乎仅适用于异常。Retryable
如果可能的话,我想为此使用一个库,并避免:
- 创建并引发异常。
- 自己编写逻辑。
我有一个具有以下签名的方法:
public Optional<String> doSomething() {
...
}
如果我得到一个空,我想重试此方法,只有在3次后返回空。Optional
Optional
我查看并找到了弹簧注释,但它似乎仅适用于异常。Retryable
如果可能的话,我想为此使用一个库,并避免:
我一直在重试中使用故障安全构建。您可以根据谓词和异常重试。
您的代码将如下所示:
private Optional<String> doSomethingWithRetry() {
RetryPolicy<Optional> retryPolicy = new RetryPolicy<Optional>()
.withMaxAttempts(3)
.handleResultIf(result -> {
System.out.println("predicate");
return !result.isPresent();
});
return Failsafe
.with(retryPolicy)
.onSuccess(response -> System.out.println("ok"))
.onFailure(response -> System.out.println("no ok"))
.get(() -> doSomething());
}
private Optional<String> doSomething() {
return Optional.of("result");
}
如果可选选项不为空,则输出为:
predicate
ok
否则看起来像:
predicate
predicate
predicate
no ok
@Retryable
(和底层的)纯粹基于例外。RetryTemplate
您可以子类 ,覆盖以检查返回值。RetryTemplate
doExecute()
您可能必须复制该方法中的大部分代码;它并不是真正设计用于覆盖呼叫而设计的。retryCallback.doWithRetry()
可以在 中使用自定义(在属性中指定)。RetryTemplate
RetryOperationsInterceptor
@Retryable
interceptor
编辑
当前代码如下所示...RetryTemplate
while (canRetry(retryPolicy, context) && !context.isExhaustedOnly()) {
try {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Retry: count=" + context.getRetryCount());
}
// Reset the last exception, so if we are successful
// the close interceptors will not think we failed...
lastException = null;
return retryCallback.doWithRetry(context);
}
catch (Throwable e) {
lastException = e;
try {
registerThrowable(retryPolicy, state, context, e);
}
catch (Exception ex) {
throw new TerminatedRetryException("Could not register throwable",
ex);
}
finally {
doOnErrorInterceptors(retryCallback, context, e);
}
...
}
您需要将其更改为类似...
while (canRetry(retryPolicy, context) && !context.isExhaustedOnly()) {
try {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Retry: count=" + context.getRetryCount());
}
// Reset the last exception, so if we are successful
// the close interceptors will not think we failed...
lastException = null;
T result = retryCallback.doWithRetry(context);
if (((Optional<String>) result).get() == null) {
try {
registerThrowable(retryPolicy, state, context, someDummyException);
}
catch (Exception ex) {
throw new TerminatedRetryException("Could not register throwable",
ex);
}
finally {
doOnErrorInterceptors(retryCallback, context, e);
}
...
}
else {
return result;
}
}
catch (Throwable e) {
...
}
哪里是欺骗上下文以增加计数器。它可以是一个字段,只需创建一次。someDummyException
static