From 22c4af69de8c9625e55810648213d56732b6b439 Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sun, 10 Nov 2024 19:27:26 +0800 Subject: [PATCH] =?UTF-8?q?feature=20#IAY66T=20=E5=AE=8C=E5=96=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lifecycle/impl/RuleCacheLifeCycle.java | 4 + .../ruleCache/RuleCacheSpringbootTest.java | 83 ++++++++++++++----- 2 files changed, 64 insertions(+), 23 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/lifecycle/impl/RuleCacheLifeCycle.java b/liteflow-core/src/main/java/com/yomahub/liteflow/lifecycle/impl/RuleCacheLifeCycle.java index b7ceb80ca..db7b9be18 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/lifecycle/impl/RuleCacheLifeCycle.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/lifecycle/impl/RuleCacheLifeCycle.java @@ -45,6 +45,10 @@ public class RuleCacheLifeCycle implements PostProcessFlowExecuteLifeCycle { } + public Cache getCache() { + return cache; + } + /** * 监听在缓存中被移除的chain */ diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringbootTest.java index c726cf940..4a63b9a53 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringbootTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringbootTest.java @@ -1,6 +1,7 @@ package com.yomahub.liteflow.test.ruleCache; import cn.hutool.core.collection.CollUtil; +import com.github.benmanes.caffeine.cache.Cache; import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder; import com.yomahub.liteflow.core.FlowExecutor; import com.yomahub.liteflow.exception.ChainNotFoundException; @@ -8,8 +9,13 @@ import com.yomahub.liteflow.flow.FlowBus; import com.yomahub.liteflow.flow.LiteflowResponse; import com.yomahub.liteflow.flow.element.Chain; import com.yomahub.liteflow.flow.element.Condition; +import com.yomahub.liteflow.lifecycle.LifeCycleHolder; +import com.yomahub.liteflow.lifecycle.PostProcessFlowExecuteLifeCycle; +import com.yomahub.liteflow.lifecycle.impl.RuleCacheLifeCycle; import com.yomahub.liteflow.test.BaseTest; +import org.checkerframework.checker.nullness.qual.NonNull; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; @@ -17,8 +23,10 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.test.context.TestPropertySource; import javax.annotation.Resource; +import java.util.HashSet; import java.util.List; import java.util.Random; +import java.util.Set; /** * Springboot环境下规则缓存测试 @@ -32,29 +40,40 @@ public class RuleCacheSpringbootTest extends BaseTest { @Resource private FlowExecutor flowExecutor; + @BeforeEach + public void reload() { + flowExecutor.reloadRule(); + // 清空缓存 + Cache cache = getCache(); + cache.invalidateAll(); + cache.cleanUp(); + } + // 测试chain被淘汰 @Test public void testRuleCache1() throws InterruptedException { - flowExecutor.reloadRule(); // 加满缓存 loadCache(); + // 缓存快照 + HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg"); // chain1 被淘汰 Assertions.assertTrue(response.isSuccess()); Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); - testEvicted("chain1"); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); } // 测试缓存数量 @Test - public void testRuleCache2() throws InterruptedException { - flowExecutor.reloadRule(); + public void testRuleCache2() { // 确保至少执行过3个不同的chain loadCache(); // 随机执行chain loadCache(100); // 等待缓存淘汰 - Thread.sleep(200); + getCache().cleanUp(); // 测试只有3个chain被编译 int count = 0; for (Chain chain : FlowBus.getChainMap().values()) { @@ -72,11 +91,13 @@ public class RuleCacheSpringbootTest extends BaseTest { // 测试chain被更新 @Test public void testRuleCache3() throws InterruptedException { - flowExecutor.reloadRule(); loadCache(); + // 缓存快照 + HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); flowExecutor.execute2Resp("chain5", "arg"); - // chain1 被淘汰 - testEvicted("chain1"); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); // 更新chain1 LiteFlowChainELBuilder .createChain() @@ -92,13 +113,15 @@ public class RuleCacheSpringbootTest extends BaseTest { // 测试chain被移除 @Test public void testRuleCache4() throws InterruptedException { - flowExecutor.reloadRule(); loadCache(); + // 缓存快照 + HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); LiteflowResponse response = flowExecutor.execute2Resp("chain5", "arg"); Assertions.assertTrue(response.isSuccess()); Assertions.assertEquals("x==>a==>c", response.getExecuteStepStr()); - // chain1被淘汰 - testEvicted("chain1"); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); // 手动移除chain5 FlowBus.removeChain("chain5"); response = flowExecutor.execute2Resp("chain5", "arg"); @@ -107,7 +130,7 @@ public class RuleCacheSpringbootTest extends BaseTest { } - // 加载缓存 + // 加载缓存, chain1、chain2、chain3 private void loadCache() { // 容量上限为3 LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); @@ -133,17 +156,31 @@ public class RuleCacheSpringbootTest extends BaseTest { // 测试 chain 被淘汰 private void testEvicted(String chanId) throws InterruptedException { Chain chain = FlowBus.getChain(chanId); - int limit = 10; // 重试上限 - int count = 0; - while (chain.isCompiled()) { - // 等待 chain 被淘汰 - Thread.sleep(100); - count++; - if (count > limit) { - throw new RuntimeException(chanId + " not be evicted"); - } - System.out.println(count); - } + getCache().cleanUp(); + Assertions.assertFalse(chain.isCompiled()); Assertions.assertNull(chain.getConditionList()); } + + public Cache getCache() { + List lifeCycleList + = LifeCycleHolder.getPostProcessFlowExecuteLifeCycleList(); + for (PostProcessFlowExecuteLifeCycle lifeCycle : lifeCycleList) { + if (lifeCycle.getClass().equals(RuleCacheLifeCycle.class)) { + RuleCacheLifeCycle ruleCacheLifeCycle = (RuleCacheLifeCycle) lifeCycle; + return ruleCacheLifeCycle.getCache(); + } + } + return null; + } + + // 获得淘汰的chain,传入淘汰前的chain集合 + // 确保只有一个被淘汰时使用 + String getEvictedChain(Set set) { + Cache cache = getCache(); + cache.cleanUp(); + Set<@NonNull String> strings = cache.asMap().keySet(); + set.removeAll(strings); + Assertions.assertEquals(1, set.size()); + return set.iterator().next(); + } }