diff --git a/extension/extension-agent/src/main/java/org/dromara/dynamictp/extension/agent/AgentAware.java b/extension/extension-agent/src/main/java/org/dromara/dynamictp/extension/agent/AgentAware.java index a3fc9dc6cc6d03bc8178f12158fc1d36d3a264a1..f09ee8d76eb754c76f06683e19b1a1374c55815a 100644 --- a/extension/extension-agent/src/main/java/org/dromara/dynamictp/extension/agent/AgentAware.java +++ b/extension/extension-agent/src/main/java/org/dromara/dynamictp/extension/agent/AgentAware.java @@ -17,6 +17,7 @@ package org.dromara.dynamictp.extension.agent; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ArrayUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; @@ -25,10 +26,7 @@ import org.dromara.dynamictp.core.support.task.runnable.DtpRunnable; import java.lang.ref.SoftReference; import java.lang.reflect.Field; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.stream.Collectors; @@ -59,7 +57,7 @@ public class AgentAware extends TaskStatAware { return "agent"; } - private DtpRunnable determineDtpRunnable(List conditionalFields, Runnable r) throws IllegalAccessException { + private DtpRunnable determineDtpRunnable(List conditionalFields, Runnable r, Set visitedClass) throws IllegalAccessException { for (Field field : conditionalFields) { if (Objects.isNull(field)) { continue; @@ -69,8 +67,13 @@ public class AgentAware extends TaskStatAware { if (o instanceof DtpRunnable) { return (DtpRunnable) o; } + if (CollUtil.contains(visitedClass, o.getClass())) { + return null; + } else { + visitedClass.add(o.getClass()); + } // 纵向查找 - DtpRunnable dtpRunnable = getDtpRunnable(o.getClass(), o); + DtpRunnable dtpRunnable = getDtpRunnable(o.getClass(), o, visitedClass); if (dtpRunnable != null) { return dtpRunnable; } @@ -78,7 +81,7 @@ public class AgentAware extends TaskStatAware { return null; } - private DtpRunnable getDtpRunnable(Class rClass, Runnable r) throws IllegalAccessException { + private DtpRunnable getDtpRunnable(Class rClass, Runnable r, Set visitedClass) throws IllegalAccessException { while (Runnable.class.isAssignableFrom(rClass)) { Field[] declaredFields = rClass.getDeclaredFields(); if (ArrayUtil.isNotEmpty(declaredFields)) { @@ -86,7 +89,7 @@ public class AgentAware extends TaskStatAware { .filter(ele -> Runnable.class.isAssignableFrom(ele.getType())) .collect(Collectors.toList()); if (CollectionUtils.isNotEmpty(conditionFields)) { - DtpRunnable dtpRunnable = determineDtpRunnable(conditionFields, r); + DtpRunnable dtpRunnable = determineDtpRunnable(conditionFields, r, visitedClass); if (Objects.nonNull(dtpRunnable)) { return dtpRunnable; } @@ -107,7 +110,7 @@ public class AgentAware extends TaskStatAware { DtpRunnable dtpRunnable = null; Class rClass = r.getClass(); try { - dtpRunnable = getDtpRunnable(rClass, r); + dtpRunnable = getDtpRunnable(rClass, r, new HashSet<>()); } catch (IllegalAccessException e) { log.error("getDtpRunnable Error", e); } diff --git a/test/test-extension/src/test/java/org/dromara/dynamictp/agent/AgentAwareTest.java b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/AgentAwareTest.java index ecd38904224ec31972711efb27916a62c86539b9..aa3dc4db5bb6d649760dc61eb5de38c529731054 100644 --- a/test/test-extension/src/test/java/org/dromara/dynamictp/agent/AgentAwareTest.java +++ b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/AgentAwareTest.java @@ -17,14 +17,20 @@ package org.dromara.dynamictp.agent; +import org.dromara.dynamictp.core.support.ThreadPoolBuilder; import org.dromara.dynamictp.extension.agent.AgentAware; import org.dromara.dynamictp.core.support.task.runnable.DtpRunnable; +import org.junit.Assert; import org.junit.Test; import org.junit.jupiter.api.Assertions; import org.springframework.util.ReflectionUtils; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; public class AgentAwareTest { @@ -124,4 +130,53 @@ public class AgentAwareTest { Assertions.assertTrue(result == dtpRunnable); } + + @Test + public void testNestRunnable() throws InvocationTargetException, IllegalAccessException { + + Runnable runnable = () -> System.out.println("test"); + DtpRunnable dtpRunnable = new DtpRunnable(runnable, runnable, "test"); + MyAgentNestWrapper myAgentNestWrapper = new MyAgentNestWrapper(dtpRunnable); + Method getDtpRunnableInstance = ReflectionUtils.findMethod(AgentAware.class, "getDtpRunnableInstance", Runnable.class); + getDtpRunnableInstance.setAccessible(true); + Object result = getDtpRunnableInstance.invoke(new AgentAware(), myAgentNestWrapper); + Assertions.assertTrue(dtpRunnable == dtpRunnable); + } + + @Test + public void testContainNestRunnable() throws InvocationTargetException, IllegalAccessException { + + Runnable runnable = () -> System.out.println("test"); + DtpRunnable dtpRunnable = new DtpRunnable(runnable, runnable, "test"); + MyAgentNestWrapper myAgentNestWrapper = new MyAgentNestWrapper(dtpRunnable); + + MyAgentContainNestWrapper myAgentContainNestWrapper = new MyAgentContainNestWrapper(myAgentNestWrapper); + + Method getDtpRunnableInstance = ReflectionUtils.findMethod(AgentAware.class, "getDtpRunnableInstance", Runnable.class); + getDtpRunnableInstance.setAccessible(true); + Object result = getDtpRunnableInstance.invoke(new AgentAware(), myAgentContainNestWrapper); + Assertions.assertTrue(dtpRunnable == dtpRunnable); + } + + @Test + public void testScheduledThreadPoolExecutor() throws InterruptedException { + ScheduledExecutorService scheduledExecutorService = ThreadPoolBuilder.newBuilder() + .dynamic(true) + .corePoolSize(1) + .scheduled() + .buildScheduled(); + + AtomicInteger count = new AtomicInteger(); + CountDownLatch downLatch = new CountDownLatch(3); + scheduledExecutorService.scheduleAtFixedRate(() -> { + if (count.get() >= 3) { + throw new RuntimeException("down"); + } + count.incrementAndGet(); + downLatch.countDown(); + }, 1, 1, TimeUnit.SECONDS); + + downLatch.await(); + Assert.assertEquals(3, count.get()); + } } diff --git a/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentContainNestWrapper.java b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentContainNestWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..956e0c42b71e518f35ca60effc65e6782577a969 --- /dev/null +++ b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentContainNestWrapper.java @@ -0,0 +1,17 @@ +package org.dromara.dynamictp.agent; + +public class MyAgentContainNestWrapper implements Runnable { + + private MyAgentNestWrapper agentNestWrapper; + + public MyAgentContainNestWrapper(MyAgentNestWrapper agentNestWrapper) { + this.agentNestWrapper = agentNestWrapper; + } + + @Override + public void run() { + System.out.println("before"); + agentNestWrapper.run(); + System.out.println("after"); + } +} diff --git a/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentNestWrapper.java b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentNestWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..b62573745ef7ccab42fad0a42d78b449fdbb875c --- /dev/null +++ b/test/test-extension/src/test/java/org/dromara/dynamictp/agent/MyAgentNestWrapper.java @@ -0,0 +1,24 @@ +package org.dromara.dynamictp.agent; + +import org.dromara.dynamictp.core.support.task.runnable.DtpRunnable; + +public class MyAgentNestWrapper implements Runnable { + + private MyAgentNestWrapper myAgentNestWrapper = this; + + private DtpRunnable dtpRunnable; + + public MyAgentNestWrapper(DtpRunnable dtpRunnable) { + this.dtpRunnable = dtpRunnable; + } + + @Override + public void run() { + System.out.println("before"); + try { + dtpRunnable.run(); + } finally { + System.out.println("finally"); + } + } +}