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;
|
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.IdUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.aizuda.easy.retry.client.common.config.EasyRetryProperties;
|
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.core.annotation.Retryable;
|
||||||
import com.aizuda.easy.retry.client.common.cache.GroupVersionCache;
|
import com.aizuda.easy.retry.client.common.cache.GroupVersionCache;
|
||||||
import com.aizuda.easy.retry.client.core.cache.RetryerInfoCache;
|
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());
|
Retryable retryable = getAnnotationParameter(invocation.getMethod());
|
||||||
String executorClassName = invocation.getThis().getClass().getName();
|
String executorClassName = invocation.getThis().getClass().getName();
|
||||||
String methodEntrance = getMethodEntrance(retryable, executorClassName);
|
String methodEntrance = getMethodEntrance(retryable, executorClassName);
|
||||||
if (StrUtil.isBlank(RetrySiteSnapshot.getMethodEntrance())) {
|
|
||||||
|
if (Propagation.REQUIRES_NEW.equals(retryable.propagation())) {
|
||||||
RetrySiteSnapshot.setMethodEntrance(methodEntrance);
|
RetrySiteSnapshot.setMethodEntrance(methodEntrance);
|
||||||
|
} else if (!RetrySiteSnapshot.existedMethodEntrance()) {
|
||||||
|
RetrySiteSnapshot.setMethodEntrance(methodEntrance);
|
||||||
|
} else {
|
||||||
|
EasyRetryLog.LOCAL.info("无需设置入口标志:[{}]", traceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
Throwable throwable = null;
|
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) {
|
if (throwable != null) {
|
||||||
throw throwable;
|
throw throwable;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
package com.aizuda.easy.retry.client.core.intercepter;
|
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.RetrySiteSnapshotContext;
|
||||||
import com.aizuda.easy.retry.client.core.exception.EasyRetryClientException;
|
import com.aizuda.easy.retry.client.core.exception.EasyRetryClientException;
|
||||||
import com.aizuda.easy.retry.client.core.loader.EasyRetrySpiLoader;
|
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.constant.SystemConstants;
|
||||||
import com.aizuda.easy.retry.common.core.model.EasyRetryHeaders;
|
import com.aizuda.easy.retry.common.core.model.EasyRetryHeaders;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Stack;
|
|
||||||
import java.util.concurrent.LinkedBlockingDeque;
|
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() {
|
public static String getMethodEntrance() {
|
||||||
Deque<String> stack = RETRY_CLASS_METHOD_ENTRANCE.get();
|
Deque<MethodEntranceMeta> stack = RETRY_CLASS_METHOD_ENTRANCE.get();
|
||||||
return stack.peek();
|
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) {
|
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())) {
|
if (Objects.isNull(RETRY_CLASS_METHOD_ENTRANCE.get())) {
|
||||||
stack = new LinkedBlockingDeque<>();
|
stack = new LinkedBlockingDeque<>();
|
||||||
}
|
|
||||||
|
|
||||||
stack.push(methodEntrance);
|
|
||||||
RETRY_CLASS_METHOD_ENTRANCE.set(stack);
|
RETRY_CLASS_METHOD_ENTRANCE.set(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MethodEntranceMeta meta;
|
||||||
|
if (!isRunning() && !isRetryFlow()) {
|
||||||
|
meta = new MethodEntranceMeta(methodEntrance);
|
||||||
|
stack.push(meta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void removeMethodEntrance() {
|
public static void removeMethodEntrance() {
|
||||||
Deque<String> stack = RETRY_CLASS_METHOD_ENTRANCE.get();
|
Deque<MethodEntranceMeta> stack = RETRY_CLASS_METHOD_ENTRANCE.get();
|
||||||
if (Objects.isNull(stack)) {
|
if (Objects.isNull(stack)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -99,15 +121,20 @@ public class RetrySiteSnapshot {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isRunning() && !isRetryFlow()) {
|
||||||
stack.pop();
|
stack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isMethodEntrance(String methodEntrance) {
|
|
||||||
if (StrUtil.isBlank(getMethodEntrance())) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return getMethodEntrance().equals(methodEntrance);
|
public static boolean isMethodEntrance(String methodEntrance) {
|
||||||
|
Deque<MethodEntranceMeta> stack = RETRY_CLASS_METHOD_ENTRANCE.get();
|
||||||
|
if (Objects.isNull(stack) || Objects.isNull(stack.peek())) {
|
||||||
|
return Boolean.FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodEntranceMeta peek = stack.peek();
|
||||||
|
return methodEntrance.equals(peek.methodEntrance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Integer getStatus() {
|
public static Integer getStatus() {
|
||||||
@ -187,12 +214,12 @@ public class RetrySiteSnapshot {
|
|||||||
public static void removeAll() {
|
public static void removeAll() {
|
||||||
|
|
||||||
removeStatus();
|
removeStatus();
|
||||||
removeMethodEntrance();
|
|
||||||
removeStage();
|
removeStage();
|
||||||
removeAttemptNumber();
|
removeAttemptNumber();
|
||||||
removeEntryMethodTime();
|
removeEntryMethodTime();
|
||||||
removeRetryHeader();
|
removeRetryHeader();
|
||||||
removeRetryStatusCode();
|
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