提交 10be9b57 作者: 方治民

refactor: 重构重试器实现 Retriever 优化测试用例

上级 729ea163
......@@ -14,7 +14,7 @@ import com.yiring.common.annotation.DownloadResponse;
import com.yiring.common.annotation.RateLimiter;
import com.yiring.common.core.I18n;
import com.yiring.common.core.Result;
import com.yiring.common.core.RetryExecutor;
import com.yiring.common.core.Retriever;
import com.yiring.common.core.Status;
import com.yiring.common.param.IdParam;
import com.yiring.common.param.PageParam;
......@@ -61,7 +61,7 @@ public class ExampleController {
final Auths auths;
final UserExtensionRepository userExtensionRepository;
final FileManageService fileManageService;
final RetryExecutor retryExecutor;
final Retriever retriever;
@RateLimiter(count = 1)
@Operation(summary = "Hello World")
......@@ -83,12 +83,12 @@ public class ExampleController {
// throw BusinessException.i18n("Code.1");
// throw new FailStatusException(Status.BAD_REQUEST, "Code.1");
// 3. 重试抛出异常
throw retryExecutor.run(
throw retriever.execute(
ctx -> {
throw new RuntimeException("retry test fail");
},
ctx -> Status.BAD_REQUEST.exception("Code.1"),
template -> RetryExecutor.setSimplePolicy(template, 3, 1000L)
Retriever::defaultPolicy
);
}
......
......@@ -2,7 +2,7 @@
package com.yiring;
import cn.hutool.core.lang.Console;
import com.yiring.common.core.RetryExecutor;
import com.yiring.common.core.Retriever;
import org.junit.jupiter.api.Test;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
......@@ -13,14 +13,16 @@ import org.springframework.retry.annotation.EnableRetry;
@EnableRetry
public class RetryTests {
RetryExecutor retry = new RetryExecutor();
Retriever retriever = new Retriever();
/**
* 简易重试,超过默认次数会抛出异常
* 简易重试
*/
@Test
void def() {
Integer value = retry.run(ctx -> {
Integer value = retriever.execute(ctx -> {
// eg: 可以在里面写需要重试的业务逻辑,例如:网络请求、数据库连接...
Console.log("retry test, {}", ctx.getRetryCount());
String text = "0.0";
......@@ -34,20 +36,24 @@ public class RetryTests {
}
/**
* 默认的退回策略
* 默认的退回策略,重试 3 次,每次间隔 1s
*/
@Test
void recover() {
Integer value = retry.run(
Integer value = retriever.execute(
ctx -> {
// eg: 可以在里面写需要重试的业务逻辑,例如:网络请求、数据库连接...
Console.log("retry test, {}", ctx.getRetryCount());
throw new RuntimeException("test");
},
ctx -> {
// eg: 可以在重试超过指定次数和规则后,返回默认值,然后业务上可以根据返回值进行相应的处理,例如:返回 null,然后判断 null 时,发送告警消息
Console.log("retry recover, {}", ctx.getRetryCount());
return 666;
},
template -> RetryExecutor.setSimplePolicy(template, 2, 1000L)
Retriever::defaultPolicy
);
Console.log("[recover] retry test result: {}", value);
}
......@@ -57,17 +63,15 @@ public class RetryTests {
*/
@Test
void custom() {
Integer value = retry.run(
Integer value = retriever.execute(
ctx -> {
// eg: 可以在里面写需要重试的业务逻辑,例如:网络请求、数据库连接...
Console.log("retry test, {}", ctx.getRetryCount());
throw new RuntimeException("test");
},
ctx -> {
Console.log("retry recover, {}", ctx.getRetryCount());
return null;
},
template -> RetryExecutor.setSimplePolicy(template, 2, 5000L)
template -> Retriever.setSimplePolicy(template, 2, 5000L)
);
Console.log("[recover] retry test result: {}", value);
Console.log("[custom] retry test result: {}", value);
}
}
......@@ -13,7 +13,7 @@ import org.springframework.retry.support.RetryTemplate;
import org.springframework.stereotype.Component;
/**
* 重试执行器
* 重试执行器(重试者)
* 用途: 主要用于解决切面重试机制的问题,减少自定义实现 AOP 重试机制的代码量
*
* @author Jim
......@@ -23,7 +23,7 @@ import org.springframework.stereotype.Component;
@Slf4j
@Component
@EnableRetry
public class RetryExecutor {
public class Retriever {
/**
* 包装重试方法实现
......@@ -33,8 +33,8 @@ public class RetryExecutor {
* @param <S> 重试业务的返回值类型
* @return 重试业务的返回值,例如:一个连接对象、网络请求结果
*/
public <S> S run(@NotNull RetrySupplier<S> accomplish) {
return run(accomplish, null, null);
public <S> S execute(@NotNull RetrySupplier<S> accomplish) {
return execute(accomplish, null, null);
}
/**
......@@ -46,8 +46,8 @@ public class RetryExecutor {
* @param <S> 重试业务的返回值类型
* @return 重试业务的返回值,例如:一个连接对象、网络请求结果
*/
public <S> S run(@NotNull RetrySupplier<S> accomplish, Consumer<RetryTemplate> consumer) {
return run(accomplish, null, consumer);
public <S> S execute(@NotNull RetrySupplier<S> accomplish, Consumer<RetryTemplate> consumer) {
return execute(accomplish, null, consumer);
}
/**
......@@ -59,7 +59,11 @@ public class RetryExecutor {
* @param <S> 重试业务的返回值类型
* @return 重试业务的返回值,例如:一个连接对象、网络请求结果
*/
public <S> S run(@NotNull RetrySupplier<S> accomplish, RetrySupplier<S> recover, Consumer<RetryTemplate> consumer) {
public <S> S execute(
@NotNull RetrySupplier<S> accomplish,
RetrySupplier<S> recover,
Consumer<RetryTemplate> consumer
) {
// 创建默认的重试模板
RetryTemplate template = RetryTemplate.builder().retryOn(Exception.class).build();
......@@ -79,7 +83,7 @@ public class RetryExecutor {
// 没有添加保底恢复实现的情况下,抛出原始异常
Throwable throwable = ctx.getLastThrowable();
log.error(
"[RetryExecutor] execute fail, retry count: {}, e: {}",
"[Retriever] execute fail, retry count: {}, e: {}",
ctx.getRetryCount(),
throwable.getMessage()
);
......@@ -89,7 +93,17 @@ public class RetryExecutor {
}
/**
* 默认的重试策略,重试 3 次,每次间隔 1s
*
* @param template 重试模板
*/
public static void defaultPolicy(RetryTemplate template) {
setSimplePolicy(template, 3, 1000L);
}
/**
* 设置简单的重试策略
* 复杂的自定义重试策略可以使用 Consumer 函数回调自行实现
*
* @param template 重试模板
* @param maxAttempts 最大重试次数
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论