feat: 3.1.0
1. 重试支持嵌套重试
This commit is contained in:
parent
28e4fa9769
commit
5174463979
@ -0,0 +1,14 @@
|
||||
package com.aizuda.easy.retry.client.core.annotation;
|
||||
|
||||
/**
|
||||
* @author: xiaowoniu
|
||||
* @date : 2024-02-05
|
||||
* @since : 3.1.0
|
||||
*/
|
||||
public enum Propagation {
|
||||
|
||||
REQUIRED,
|
||||
REQUIRES_NEW
|
||||
;
|
||||
|
||||
}
|
@ -121,6 +121,11 @@ public @interface Retryable {
|
||||
*/
|
||||
TimeUnit unit() default TimeUnit.MILLISECONDS;
|
||||
|
||||
|
||||
/**
|
||||
* 重试传播机制
|
||||
*
|
||||
* @return Propagation
|
||||
*/
|
||||
Propagation propagation() default Propagation.REQUIRED;
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package com.aizuda.easy.retry.client.core.intercepter;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.aizuda.easy.retry.client.common.config.EasyRetryProperties;
|
||||
import com.aizuda.easy.retry.client.core.annotation.Propagation;
|
||||
import com.aizuda.easy.retry.client.core.annotation.Retryable;
|
||||
import com.aizuda.easy.retry.client.common.cache.GroupVersionCache;
|
||||
import com.aizuda.easy.retry.client.core.cache.RetryerInfoCache;
|
||||
@ -73,8 +74,13 @@ public class EasyRetryInterceptor implements MethodInterceptor, AfterAdvice, Ser
|
||||
Retryable retryable = getAnnotationParameter(invocation.getMethod());
|
||||
String executorClassName = invocation.getThis().getClass().getName();
|
||||
String methodEntrance = getMethodEntrance(retryable, executorClassName);
|
||||
if (StrUtil.isBlank(RetrySiteSnapshot.getMethodEntrance())) {
|
||||
|
||||
if (Propagation.REQUIRES_NEW.equals(retryable.propagation())) {
|
||||
RetrySiteSnapshot.setMethodEntrance(methodEntrance);
|
||||
} else if (!RetrySiteSnapshot.existedMethodEntrance()) {
|
||||
RetrySiteSnapshot.setMethodEntrance(methodEntrance);
|
||||
} else {
|
||||
EasyRetryLog.LOCAL.info("无需设置入口标志:[{}]", traceId);
|
||||
}
|
||||
|
||||
Throwable throwable = null;
|
||||
@ -112,6 +118,11 @@ public class EasyRetryInterceptor implements MethodInterceptor, AfterAdvice, Ser
|
||||
}
|
||||
}
|
||||
|
||||
// 无需开启重试的场景,需要清除缓存信息
|
||||
if ((RetrySiteSnapshot.isMethodEntrance(methodEntrance) && !RetrySiteSnapshot.isRunning())) {
|
||||
RetrySiteSnapshot.removeAll();
|
||||
}
|
||||
|
||||
if (throwable != null) {
|
||||
throw throwable;
|
||||
} else {
|
||||
|
@ -1,18 +1,18 @@
|
||||
package com.aizuda.easy.retry.client.core.intercepter;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.aizuda.easy.retry.client.core.RetrySiteSnapshotContext;
|
||||
import com.aizuda.easy.retry.client.core.exception.EasyRetryClientException;
|
||||
import com.aizuda.easy.retry.client.core.loader.EasyRetrySpiLoader;
|
||||
import com.aizuda.easy.retry.common.core.constant.SystemConstants;
|
||||
import com.aizuda.easy.retry.common.core.model.EasyRetryHeaders;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Deque;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Stack;
|
||||
import java.util.concurrent.LinkedBlockingDeque;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* 重试现场记录器
|
||||
@ -30,7 +30,7 @@ public class RetrySiteSnapshot {
|
||||
/**
|
||||
* 标记重试方法入口
|
||||
*/
|
||||
private static final RetrySiteSnapshotContext<Deque<String>> RETRY_CLASS_METHOD_ENTRANCE = EasyRetrySpiLoader.loadRetrySiteSnapshotContext();
|
||||
private static final RetrySiteSnapshotContext<Deque<MethodEntranceMeta>> RETRY_CLASS_METHOD_ENTRANCE = EasyRetrySpiLoader.loadRetrySiteSnapshotContext();
|
||||
|
||||
/**
|
||||
* 重试状态
|
||||
@ -74,22 +74,44 @@ public class RetrySiteSnapshot {
|
||||
}
|
||||
|
||||
public static String getMethodEntrance() {
|
||||
Deque<String> stack = RETRY_CLASS_METHOD_ENTRANCE.get();
|
||||
return stack.peek();
|
||||
Deque<MethodEntranceMeta> stack = RETRY_CLASS_METHOD_ENTRANCE.get();
|
||||
if (Objects.isNull(stack) || Objects.isNull(stack.peek())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return stack.peek().methodEntrance;
|
||||
}
|
||||
|
||||
public static boolean existedMethodEntrance() {
|
||||
Deque<MethodEntranceMeta> stack = RETRY_CLASS_METHOD_ENTRANCE.get();
|
||||
if (Objects.isNull(stack)) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
MethodEntranceMeta meta = stack.peek();
|
||||
if(Objects.isNull(meta)) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
|
||||
public static void setMethodEntrance(String methodEntrance) {
|
||||
Deque<String> stack = RETRY_CLASS_METHOD_ENTRANCE.get();
|
||||
Deque<MethodEntranceMeta> stack = RETRY_CLASS_METHOD_ENTRANCE.get();
|
||||
if (Objects.isNull(RETRY_CLASS_METHOD_ENTRANCE.get())) {
|
||||
stack = new LinkedBlockingDeque<>();
|
||||
RETRY_CLASS_METHOD_ENTRANCE.set(stack);
|
||||
}
|
||||
|
||||
stack.push(methodEntrance);
|
||||
RETRY_CLASS_METHOD_ENTRANCE.set(stack);
|
||||
MethodEntranceMeta meta;
|
||||
if (!isRunning() && !isRetryFlow()) {
|
||||
meta = new MethodEntranceMeta(methodEntrance);
|
||||
stack.push(meta);
|
||||
}
|
||||
}
|
||||
|
||||
public static void removeMethodEntrance() {
|
||||
Deque<String> stack = RETRY_CLASS_METHOD_ENTRANCE.get();
|
||||
Deque<MethodEntranceMeta> stack = RETRY_CLASS_METHOD_ENTRANCE.get();
|
||||
if (Objects.isNull(stack)) {
|
||||
return;
|
||||
}
|
||||
@ -99,15 +121,20 @@ public class RetrySiteSnapshot {
|
||||
return;
|
||||
}
|
||||
|
||||
stack.pop();
|
||||
if (!isRunning() && !isRetryFlow()) {
|
||||
stack.pop();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean isMethodEntrance(String methodEntrance) {
|
||||
if (StrUtil.isBlank(getMethodEntrance())) {
|
||||
return false;
|
||||
Deque<MethodEntranceMeta> stack = RETRY_CLASS_METHOD_ENTRANCE.get();
|
||||
if (Objects.isNull(stack) || Objects.isNull(stack.peek())) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
return getMethodEntrance().equals(methodEntrance);
|
||||
MethodEntranceMeta peek = stack.peek();
|
||||
return methodEntrance.equals(peek.methodEntrance);
|
||||
}
|
||||
|
||||
public static Integer getStatus() {
|
||||
@ -187,12 +214,12 @@ public class RetrySiteSnapshot {
|
||||
public static void removeAll() {
|
||||
|
||||
removeStatus();
|
||||
removeMethodEntrance();
|
||||
removeStage();
|
||||
removeAttemptNumber();
|
||||
removeEntryMethodTime();
|
||||
removeRetryHeader();
|
||||
removeRetryStatusCode();
|
||||
removeMethodEntrance();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -260,4 +287,13 @@ public class RetrySiteSnapshot {
|
||||
|
||||
}
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public static class MethodEntranceMeta {
|
||||
|
||||
// private AtomicInteger depth;
|
||||
|
||||
private String methodEntrance;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user