From 2903d7c9c2f546a51c47f3d6126beff800bfda8e Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sat, 9 Nov 2024 18:20:16 +0800 Subject: [PATCH 01/34] =?UTF-8?q?feature=20#IAY66T=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- liteflow-core/pom.xml | 4 ++ ...eCachePostProcessFlowExecuteLifeCycle.java | 67 +++++++++++++++++++ pom.xml | 6 ++ 3 files changed, 77 insertions(+) create mode 100644 liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RuleCachePostProcessFlowExecuteLifeCycle.java diff --git a/liteflow-core/pom.xml b/liteflow-core/pom.xml index b6da77fe2..5d79cd668 100644 --- a/liteflow-core/pom.xml +++ b/liteflow-core/pom.xml @@ -59,5 +59,9 @@ commons-io commons-io + + com.github.ben-manes.caffeine + caffeine + diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RuleCachePostProcessFlowExecuteLifeCycle.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RuleCachePostProcessFlowExecuteLifeCycle.java new file mode 100644 index 000000000..f3a607ff8 --- /dev/null +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RuleCachePostProcessFlowExecuteLifeCycle.java @@ -0,0 +1,67 @@ +package com.yomahub.liteflow.flow.cache; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.ObjectUtil; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.RemovalCause; +import com.github.benmanes.caffeine.cache.RemovalListener; +import com.yomahub.liteflow.flow.FlowBus; +import com.yomahub.liteflow.flow.element.Chain; +import com.yomahub.liteflow.flow.element.Condition; +import com.yomahub.liteflow.lifecycle.PostProcessFlowExecuteLifeCycle; +import com.yomahub.liteflow.slot.Slot; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.checkerframework.checker.nullness.qual.Nullable; + +import java.util.List; + +/** + * Chain执行前的缓存处理 + * @author DaleLee + * @since + */ +public class RuleCachePostProcessFlowExecuteLifeCycle implements PostProcessFlowExecuteLifeCycle { + /** + * 缓存 + */ + private final Cache cache; + + public RuleCachePostProcessFlowExecuteLifeCycle(int capacity) { + this.cache = Caffeine.newBuilder() + .maximumSize(capacity) + .evictionListener(new ChainRemovalListener()) + .build(); + } + + @Override + public void postProcessBeforeFlowExecute(String chainId, Slot slot) { + Chain chain = FlowBus.getChain(chainId); + if (ObjectUtil.isNull(chain)) { + return; + } + // 记录在缓存中 + cache.put(chainId, chain); + } + + @Override + public void postProcessAfterFlowExecute(String chainId, Slot slot) { + + } + + /** + * 监听在缓存中被移除的chain + */ + private static class ChainRemovalListener implements RemovalListener { + + @Override + public void onRemoval(@Nullable String chanId, @Nullable Chain chain, @NonNull RemovalCause removalCause) { + List conditionList = chain.getConditionList(); + // 清空condition 并将chain设置为未编译 + if (CollUtil.isNotEmpty(conditionList)) { + conditionList.clear(); + } + chain.setCompiled(false); + } + } +} diff --git a/pom.xml b/pom.xml index 9dc40ddfa..88f203932 100644 --- a/pom.xml +++ b/pom.xml @@ -78,6 +78,7 @@ 3.1.12 1.9.23 1.3.6 + 2.9.3 @@ -326,6 +327,11 @@ liquor-eval ${liquor.version} + + com.github.ben-manes.caffeine + caffeine + ${caffeine.version} + From 513a3f3ed103ec468d891ccad36fc2c735b567d5 Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sat, 9 Nov 2024 19:18:14 +0800 Subject: [PATCH 02/34] =?UTF-8?q?feature=20#IAY66T=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=BC=93=E5=AD=98=E5=AE=B9=E9=87=8F=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../liteflow/property/LiteflowConfig.java | 16 ++++++++++++++++ .../liteflow/springboot/LiteflowProperty.java | 11 +++++++++++ .../LiteflowPropertyAutoConfiguration.java | 1 + ...additional-spring-configuration-metadata.json | 6 ++++++ 4 files changed, 34 insertions(+) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java b/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java index 90ba42c5c..e351b257f 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java @@ -127,6 +127,9 @@ public class LiteflowConfig { //是否启用节点实例ID private Boolean enableNodeInstanceId; + // 规则缓存容量 + private Integer ruleCacheCapacity; + public Boolean getEnableMonitorFile() { return enableMonitorFile; } @@ -524,4 +527,17 @@ public class LiteflowConfig { public void setEnableNodeInstanceId(Boolean enableNodeInstanceId) { this.enableNodeInstanceId = enableNodeInstanceId; } + + + public Integer getRuleCacheCapacity() { + return ruleCacheCapacity; + } + + public void setRuleCacheCapacity(Integer ruleCacheCapacity) { + this.ruleCacheCapacity = ruleCacheCapacity; + } + + public boolean isRuleCacheEnabled() { + return ObjectUtil.isNotNull(ruleCacheCapacity) && ruleCacheCapacity > 0; + } } diff --git a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java index 6dfd031fc..5e2d45095 100644 --- a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java +++ b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java @@ -104,6 +104,9 @@ public class LiteflowProperty { //是否启用节点实例ID private boolean enableNodeInstanceId; + // 规则缓存容量 + private Integer ruleCacheCapacity; + public boolean isEnableMonitorFile() { return enableMonitorFile; } @@ -347,4 +350,12 @@ public class LiteflowProperty { public void setEnableNodeInstanceId(boolean enableNodeInstanceId) { this.enableNodeInstanceId = enableNodeInstanceId; } + + public Integer getRuleCacheCapacity() { + return ruleCacheCapacity; + } + + public void setRuleCacheCapacity(Integer ruleCacheCapacity) { + this.ruleCacheCapacity = ruleCacheCapacity; + } } diff --git a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java index 7a4124f1f..5ea57f1f9 100644 --- a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java +++ b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java @@ -55,6 +55,7 @@ public class LiteflowPropertyAutoConfiguration { liteflowConfig.setPeriod(liteflowMonitorProperty.getPeriod()); liteflowConfig.setScriptSetting(property.getScriptSetting()); liteflowConfig.setEnableNodeInstanceId(property.isEnableNodeInstanceId()); + liteflowConfig.setRuleCacheCapacity(property.getRuleCacheCapacity()); return liteflowConfig; } diff --git a/liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 9d293d9cf..6875189ff 100644 --- a/liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -227,6 +227,12 @@ "description": "enable node instance id", "sourceType": "com.yomahub.liteflow.springboot.LiteflowProperty", "defaultValue": false + }, + { + "name": "liteflow.liteflow.rule-cache-capacity", + "type": "java.lang.Integer", + "description": "Set the rules cache capacity.", + "sourceType": "com.yomahub.liteflow.springboot.LiteflowProperty" } ] } \ No newline at end of file From 917c98cc4863f8f3649c00d2d33ebe4a6fb2a56c Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sat, 9 Nov 2024 19:56:37 +0800 Subject: [PATCH 03/34] =?UTF-8?q?feature=20#IAY66T=20=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/core/FlowExecutor.java | 14 +++++-- ...LifeCycle.java => RuleCacheLifeCycle.java} | 39 +++++++++---------- 2 files changed, 29 insertions(+), 24 deletions(-) rename liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/{RuleCachePostProcessFlowExecuteLifeCycle.java => RuleCacheLifeCycle.java} (59%) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index 50118790e..55387e53d 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -20,13 +20,13 @@ import com.yomahub.liteflow.enums.ParseModeEnum; import com.yomahub.liteflow.exception.*; import com.yomahub.liteflow.flow.FlowBus; import com.yomahub.liteflow.flow.LiteflowResponse; +import com.yomahub.liteflow.flow.cache.RuleCacheLifeCycle; import com.yomahub.liteflow.flow.element.Chain; import com.yomahub.liteflow.flow.element.Node; import com.yomahub.liteflow.flow.element.Rollbackable; import com.yomahub.liteflow.flow.entity.CmpStep; import com.yomahub.liteflow.flow.id.IdGeneratorHolder; import com.yomahub.liteflow.lifecycle.LifeCycleHolder; -import com.yomahub.liteflow.lifecycle.PostProcessFlowExecuteLifeCycle; import com.yomahub.liteflow.log.LFLog; import com.yomahub.liteflow.log.LFLoggerManager; import com.yomahub.liteflow.monitor.MonitorFile; @@ -45,10 +45,7 @@ import com.yomahub.liteflow.thread.ExecutorHelper; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; -import java.util.function.Consumer; import java.util.function.Function; -import java.util.function.Predicate; -import java.util.function.Supplier; import java.util.stream.Collectors; /** @@ -103,6 +100,15 @@ public class FlowExecutor { IdGeneratorHolder.init(); } + // 规则缓存 + if (isStart && liteflowConfig.isRuleCacheEnabled()) { + Integer capacity = liteflowConfig.getRuleCacheCapacity(); + RuleCacheLifeCycle ruleCacheLifeCycle = new RuleCacheLifeCycle(capacity); + LifeCycleHolder.addLifeCycle(ruleCacheLifeCycle); + // 执行时才解析chain + liteflowConfig.setParseMode(ParseModeEnum.PARSE_ONE_ON_FIRST_EXEC); + } + String ruleSource = liteflowConfig.getRuleSource(); if (StrUtil.isBlank(ruleSource)) { // 查看有没有Parser的SPI实现 diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RuleCachePostProcessFlowExecuteLifeCycle.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RuleCacheLifeCycle.java similarity index 59% rename from liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RuleCachePostProcessFlowExecuteLifeCycle.java rename to liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RuleCacheLifeCycle.java index f3a607ff8..a2618c4cd 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RuleCachePostProcessFlowExecuteLifeCycle.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RuleCacheLifeCycle.java @@ -1,6 +1,5 @@ package com.yomahub.liteflow.flow.cache; -import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; @@ -8,26 +7,23 @@ import com.github.benmanes.caffeine.cache.RemovalCause; import com.github.benmanes.caffeine.cache.RemovalListener; import com.yomahub.liteflow.flow.FlowBus; import com.yomahub.liteflow.flow.element.Chain; -import com.yomahub.liteflow.flow.element.Condition; import com.yomahub.liteflow.lifecycle.PostProcessFlowExecuteLifeCycle; import com.yomahub.liteflow.slot.Slot; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.List; - /** * Chain执行前的缓存处理 * @author DaleLee * @since */ -public class RuleCachePostProcessFlowExecuteLifeCycle implements PostProcessFlowExecuteLifeCycle { - /** - * 缓存 - */ - private final Cache cache; +public class RuleCacheLifeCycle implements PostProcessFlowExecuteLifeCycle { + // 缓存 + private final Cache cache; + // 在缓存中与key关联的虚拟值 + private static final Object PRESENT = new Object(); - public RuleCachePostProcessFlowExecuteLifeCycle(int capacity) { + public RuleCacheLifeCycle(int capacity) { this.cache = Caffeine.newBuilder() .maximumSize(capacity) .evictionListener(new ChainRemovalListener()) @@ -36,12 +32,13 @@ public class RuleCachePostProcessFlowExecuteLifeCycle implements PostProcessFlow @Override public void postProcessBeforeFlowExecute(String chainId, Slot slot) { - Chain chain = FlowBus.getChain(chainId); - if (ObjectUtil.isNull(chain)) { + if (!FlowBus.containChain(chainId)) { return; } - // 记录在缓存中 - cache.put(chainId, chain); + // 记录chainId在缓存中 + // 这里不记录实际的chain是因为chain之后有可能在FlowBus中被移除 + // 以FlowBus中实际存在的chain为准 + cache.put(chainId, PRESENT); } @Override @@ -52,15 +49,17 @@ public class RuleCachePostProcessFlowExecuteLifeCycle implements PostProcessFlow /** * 监听在缓存中被移除的chain */ - private static class ChainRemovalListener implements RemovalListener { + private static class ChainRemovalListener implements RemovalListener { @Override - public void onRemoval(@Nullable String chanId, @Nullable Chain chain, @NonNull RemovalCause removalCause) { - List conditionList = chain.getConditionList(); - // 清空condition 并将chain设置为未编译 - if (CollUtil.isNotEmpty(conditionList)) { - conditionList.clear(); + public void onRemoval(@Nullable String chanId, @Nullable Object object, @NonNull RemovalCause removalCause) { + Chain chain = FlowBus.getChain(chanId); + // chain可能已经在FlowBus中被移除了 + if (ObjectUtil.isNull(chain)) { + return; } + // 清空condition并将chain设置为未编译 + chain.setConditionList(null); chain.setCompiled(false); } } From 7a63f7cec9d908b106c60bb4b93465db04dda778 Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sat, 9 Nov 2024 20:36:04 +0800 Subject: [PATCH 04/34] =?UTF-8?q?feature=20#IAY66T=20=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/core/FlowExecutor.java | 2 +- .../impl}/RuleCacheLifeCycle.java | 2 +- .../ruleCache/RuleCacheSpringbootTest.java | 26 +++++++++++++++++++ .../liteflow/test/ruleCache/cmp/ACmp.java | 20 ++++++++++++++ .../liteflow/test/ruleCache/cmp/BCmp.java | 21 +++++++++++++++ .../liteflow/test/ruleCache/cmp/CCmp.java | 20 ++++++++++++++ .../liteflow/test/ruleCache/cmp/XCmp.java | 12 +++++++++ .../ruleCache/application.properties | 2 ++ .../src/test/resources/ruleCache/flow.el.xml | 23 ++++++++++++++++ 9 files changed, 126 insertions(+), 2 deletions(-) rename liteflow-core/src/main/java/com/yomahub/liteflow/{flow/cache => lifecycle/impl}/RuleCacheLifeCycle.java (98%) create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringbootTest.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/application.properties create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/flow.el.xml diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index 55387e53d..447fda2f2 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -20,7 +20,7 @@ import com.yomahub.liteflow.enums.ParseModeEnum; import com.yomahub.liteflow.exception.*; import com.yomahub.liteflow.flow.FlowBus; import com.yomahub.liteflow.flow.LiteflowResponse; -import com.yomahub.liteflow.flow.cache.RuleCacheLifeCycle; +import com.yomahub.liteflow.lifecycle.impl.RuleCacheLifeCycle; import com.yomahub.liteflow.flow.element.Chain; import com.yomahub.liteflow.flow.element.Node; import com.yomahub.liteflow.flow.element.Rollbackable; diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RuleCacheLifeCycle.java b/liteflow-core/src/main/java/com/yomahub/liteflow/lifecycle/impl/RuleCacheLifeCycle.java similarity index 98% rename from liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RuleCacheLifeCycle.java rename to liteflow-core/src/main/java/com/yomahub/liteflow/lifecycle/impl/RuleCacheLifeCycle.java index a2618c4cd..a6ef2fb8f 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RuleCacheLifeCycle.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/lifecycle/impl/RuleCacheLifeCycle.java @@ -1,4 +1,4 @@ -package com.yomahub.liteflow.flow.cache; +package com.yomahub.liteflow.lifecycle.impl; import cn.hutool.core.util.ObjectUtil; import com.github.benmanes.caffeine.cache.Cache; 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 new file mode 100644 index 000000000..51cecb3c0 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringbootTest.java @@ -0,0 +1,26 @@ +package com.yomahub.liteflow.test.ruleCache; + +import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.test.BaseTest; +import com.yomahub.liteflow.test.rollback.RollbackSpringbootTest; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.test.context.TestPropertySource; + +import javax.annotation.Resource; + +@TestPropertySource(value = "classpath:/ruleCache/application.properties") +@SpringBootTest(classes = RuleCacheSpringbootTest.class) +@EnableAutoConfiguration +@ComponentScan({ "com.yomahub.liteflow.test.ruleCache.cmp" }) +public class RuleCacheSpringbootTest extends BaseTest { + @Resource + private FlowExecutor flowExecutor; + + @Test + public void testRuleCache() throws Exception{ + + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java new file mode 100644 index 000000000..e5999686e --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java @@ -0,0 +1,20 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.ruleCache.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("a") +public class ACmp extends NodeComponent { + + @Override + public void process() { + System.out.println("ACmp executed!"); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java new file mode 100644 index 000000000..c79f55d47 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java @@ -0,0 +1,21 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.ruleCache.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("b") +public class BCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("BCmp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java new file mode 100644 index 000000000..a5ba32f37 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java @@ -0,0 +1,20 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.ruleCache.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("c") +public class CCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("CCmp executed!"); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java new file mode 100644 index 000000000..1c71b836c --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java @@ -0,0 +1,12 @@ +package com.yomahub.liteflow.test.ruleCache.cmp; + +import com.yomahub.liteflow.core.NodeBooleanComponent; +import org.springframework.stereotype.Component; + +@Component("x") +public class XCmp extends NodeBooleanComponent { + @Override + public boolean processBoolean() throws Exception { + return true; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/application.properties b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/application.properties new file mode 100644 index 000000000..20fbd564f --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/application.properties @@ -0,0 +1,2 @@ +liteflow.rule-source=ruleCache/flow.el.xml +liteflow.rule-cache-capacity=3 \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/flow.el.xml b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/flow.el.xml new file mode 100644 index 000000000..1de85b0da --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/flow.el.xml @@ -0,0 +1,23 @@ + + + + THEN(a, b); + + + + THEN(a, c); + + + + THEN(c, b); + + + + THEN(IF(x, a), b); + + + + THEN(IF(x, a), c); + + + \ No newline at end of file From 6cb79573d98f3fa324ac7d0c1db37cb1ec0e9a6b Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sat, 9 Nov 2024 22:49:28 +0800 Subject: [PATCH 05/34] =?UTF-8?q?feature=20#IAY66T=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=8D=95=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ruleCache/RuleCacheSpringbootTest.java | 78 ++++++++++++++++++- .../src/test/resources/ruleCache/flow.el.xml | 2 +- 2 files changed, 78 insertions(+), 2 deletions(-) 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 51cecb3c0..806e676d1 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,8 +1,14 @@ package com.yomahub.liteflow.test.ruleCache; +import cn.hutool.core.collection.CollUtil; import com.yomahub.liteflow.core.FlowExecutor; +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.test.BaseTest; import com.yomahub.liteflow.test.rollback.RollbackSpringbootTest; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; @@ -10,6 +16,8 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.test.context.TestPropertySource; import javax.annotation.Resource; +import java.util.List; +import java.util.Random; @TestPropertySource(value = "classpath:/ruleCache/application.properties") @SpringBootTest(classes = RuleCacheSpringbootTest.class) @@ -19,8 +27,76 @@ public class RuleCacheSpringbootTest extends BaseTest { @Resource private FlowExecutor flowExecutor; + // 测试chain被淘汰 @Test - public void testRuleCache() throws Exception{ + public void testRuleCache1() throws InterruptedException { + // 加满缓存 + loadCache(); + LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg"); + // chain1 被淘汰 + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); + testEvicted("chain1"); + } + + // 测试chain被手动移除 + @Test + public void testRuleCache2() throws InterruptedException { + // 随机执行chain + loadCache(100); + Thread.sleep(100); + // 测试只有3个chain被编译 + int count = 0; + for (Chain chain : FlowBus.getChainMap().values()) { + List conditionList = chain.getConditionList(); + if (chain.isCompiled()) { + Assertions.assertTrue(CollUtil.isNotEmpty(conditionList)); + count++; + } else { + Assertions.assertNull(conditionList); + } + } + Assertions.assertEquals(3, count); } + + // 加载缓存 + private void loadCache() { + // 容量上限为3 + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("a==>b", response.getExecuteStepStr()); + response = flowExecutor.execute2Resp("chain2", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("a==>c", response.getExecuteStepStr()); + response = flowExecutor.execute2Resp("chain3", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("b==>c", response.getExecuteStepStr()); + } + + private void loadCache(int count) { + // 随机执行chain + Random random = new Random(); + for (int i = 0; i < count; i++) { + int id = random.nextInt(5) + 1; + flowExecutor.execute2Resp("chain" + id); + } + } + + // 测试 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); + } + Assertions.assertNull(chain.getConditionList()); + } } diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/flow.el.xml b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/flow.el.xml index 1de85b0da..08df154be 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/flow.el.xml +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/flow.el.xml @@ -9,7 +9,7 @@ - THEN(c, b); + THEN(b, c); From 6504394dd47eeb7f3e66a3ce52515e5b6b4b1c1e Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sun, 10 Nov 2024 17:30:40 +0800 Subject: [PATCH 06/34] =?UTF-8?q?feature=20#IAY66T=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=8D=95=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lifecycle/impl/RuleCacheLifeCycle.java | 11 ++-- .../ruleCache/RuleCacheSpringbootTest.java | 55 +++++++++++++++++-- 2 files changed, 56 insertions(+), 10 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 a6ef2fb8f..b7ceb80ca 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 @@ -32,13 +32,12 @@ public class RuleCacheLifeCycle implements PostProcessFlowExecuteLifeCycle { @Override public void postProcessBeforeFlowExecute(String chainId, Slot slot) { - if (!FlowBus.containChain(chainId)) { - return; + if (FlowBus.containChain(chainId)) { + // 记录chainId在缓存中 + // 这里不记录实际的chain是因为chain之后有可能在FlowBus中被移除 + // 或被更新,以FlowBus中实际存在的chain为准 + cache.put(chainId, PRESENT); } - // 记录chainId在缓存中 - // 这里不记录实际的chain是因为chain之后有可能在FlowBus中被移除 - // 以FlowBus中实际存在的chain为准 - cache.put(chainId, PRESENT); } @Override 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 806e676d1..c726cf940 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,13 +1,14 @@ package com.yomahub.liteflow.test.ruleCache; import cn.hutool.core.collection.CollUtil; +import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder; import com.yomahub.liteflow.core.FlowExecutor; +import com.yomahub.liteflow.exception.ChainNotFoundException; 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.test.BaseTest; -import com.yomahub.liteflow.test.rollback.RollbackSpringbootTest; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -19,6 +20,10 @@ import javax.annotation.Resource; import java.util.List; import java.util.Random; +/** + * Springboot环境下规则缓存测试 + * @author DaleLee + */ @TestPropertySource(value = "classpath:/ruleCache/application.properties") @SpringBootTest(classes = RuleCacheSpringbootTest.class) @EnableAutoConfiguration @@ -30,6 +35,7 @@ public class RuleCacheSpringbootTest extends BaseTest { // 测试chain被淘汰 @Test public void testRuleCache1() throws InterruptedException { + flowExecutor.reloadRule(); // 加满缓存 loadCache(); LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg"); @@ -39,12 +45,16 @@ public class RuleCacheSpringbootTest extends BaseTest { testEvicted("chain1"); } - // 测试chain被手动移除 + // 测试缓存数量 @Test public void testRuleCache2() throws InterruptedException { + flowExecutor.reloadRule(); + // 确保至少执行过3个不同的chain + loadCache(); // 随机执行chain loadCache(100); - Thread.sleep(100); + // 等待缓存淘汰 + Thread.sleep(200); // 测试只有3个chain被编译 int count = 0; for (Chain chain : FlowBus.getChainMap().values()) { @@ -57,9 +67,46 @@ public class RuleCacheSpringbootTest extends BaseTest { } } Assertions.assertEquals(3, count); - } + // 测试chain被更新 + @Test + public void testRuleCache3() throws InterruptedException { + flowExecutor.reloadRule(); + loadCache(); + flowExecutor.execute2Resp("chain5", "arg"); + // chain1 被淘汰 + testEvicted("chain1"); + // 更新chain1 + LiteFlowChainELBuilder + .createChain() + .setChainId("chain1") + .setEL("THEN(a, b, c)") + .build(); + // 重新执行chain1 + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("a==>b==>c", response.getExecuteStepStr()); + } + + // 测试chain被移除 + @Test + public void testRuleCache4() throws InterruptedException { + flowExecutor.reloadRule(); + loadCache(); + LiteflowResponse response = flowExecutor.execute2Resp("chain5", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("x==>a==>c", response.getExecuteStepStr()); + // chain1被淘汰 + testEvicted("chain1"); + // 手动移除chain5 + FlowBus.removeChain("chain5"); + response = flowExecutor.execute2Resp("chain5", "arg"); + Assertions.assertFalse(response.isSuccess()); + Assertions.assertEquals(ChainNotFoundException.class, response.getCause().getClass()); + } + + // 加载缓存 private void loadCache() { // 容量上限为3 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 07/34] =?UTF-8?q?feature=20#IAY66T=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E4=BB=A3=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(); + } } From 28685314a809072a51cb3bdef1f4e7630b7f4e21 Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Thu, 5 Dec 2024 22:57:39 +0800 Subject: [PATCH 08/34] =?UTF-8?q?feature=20#IAY66T=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E8=A7=84=E5=88=99=E7=BC=93=E5=AD=98=E5=BC=80=E5=85=B3=E9=85=8D?= =?UTF-8?q?=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/yomahub/liteflow/core/FlowExecutor.java | 2 +- .../liteflow/property/LiteflowConfig.java | 17 +++++++++++++---- .../liteflow/springboot/LiteflowProperty.java | 11 +++++++++++ .../LiteflowPropertyAutoConfiguration.java | 1 + ...dditional-spring-configuration-metadata.json | 11 +++++++++-- .../META-INF/liteflow-default.properties | 1 + .../resources/ruleCache/application.properties | 1 + 7 files changed, 37 insertions(+), 7 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index 357e1ad06..58bbec787 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -101,7 +101,7 @@ public class FlowExecutor { } // 规则缓存 - if (isStart && liteflowConfig.isRuleCacheEnabled()) { + if (isStart && liteflowConfig.getEnableRuleCache()) { Integer capacity = liteflowConfig.getRuleCacheCapacity(); RuleCacheLifeCycle ruleCacheLifeCycle = new RuleCacheLifeCycle(capacity); LifeCycleHolder.addLifeCycle(ruleCacheLifeCycle); diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java b/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java index 07cae7527..a13367421 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java @@ -113,6 +113,9 @@ public class LiteflowConfig { //是否启用节点实例ID private Boolean enableNodeInstanceId; + // 是否启用规则缓存 + private Boolean enableRuleCache; + // 规则缓存容量 private Integer ruleCacheCapacity; @@ -485,6 +488,16 @@ public class LiteflowConfig { this.enableNodeInstanceId = enableNodeInstanceId; } + public Boolean getEnableRuleCache() { + if (ObjectUtil.isNull(enableRuleCache)) { + return Boolean.FALSE; + } + return enableRuleCache; + } + + public void setEnableRuleCache(Boolean enableRuleCache) { + this.enableRuleCache = enableRuleCache; + } public Integer getRuleCacheCapacity() { return ruleCacheCapacity; @@ -493,8 +506,4 @@ public class LiteflowConfig { public void setRuleCacheCapacity(Integer ruleCacheCapacity) { this.ruleCacheCapacity = ruleCacheCapacity; } - - public boolean isRuleCacheEnabled() { - return ObjectUtil.isNotNull(ruleCacheCapacity) && ruleCacheCapacity > 0; - } } diff --git a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java index 6850a83ca..8b7cdc12e 100644 --- a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java +++ b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java @@ -99,6 +99,9 @@ public class LiteflowProperty { //是否启用节点实例ID private boolean enableNodeInstanceId; + // 是否启用规则缓存 + private Boolean enableRuleCache; + // 规则缓存容量 private Integer ruleCacheCapacity; @@ -341,4 +344,12 @@ public class LiteflowProperty { public void setRuleCacheCapacity(Integer ruleCacheCapacity) { this.ruleCacheCapacity = ruleCacheCapacity; } + + public Boolean isEnableRuleCache() { + return enableRuleCache; + } + + public void setEnableRuleCache(Boolean enableRuleCache) { + this.enableRuleCache = enableRuleCache; + } } diff --git a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java index 6668b1ef7..e4b9c4f50 100644 --- a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java +++ b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java @@ -53,6 +53,7 @@ public class LiteflowPropertyAutoConfiguration { liteflowConfig.setGlobalThreadPoolQueueSize(property.getGlobalThreadPoolQueueSize()); liteflowConfig.setGlobalThreadPoolSize(property.getGlobalThreadPoolSize()); liteflowConfig.setEnableNodeInstanceId(property.isEnableNodeInstanceId()); + liteflowConfig.setEnableRuleCache(property.isEnableRuleCache()); liteflowConfig.setRuleCacheCapacity(property.getRuleCacheCapacity()); return liteflowConfig; } diff --git a/liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json index a68e2992a..89cb4d599 100644 --- a/liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -208,9 +208,16 @@ "defaultValue": false }, { - "name": "liteflow.liteflow.rule-cache-capacity", + "name": "liteflow.enable-rule-cache", + "type": "java.lang.Boolean", + "description": "Enable rule cache.", + "sourceType": "com.yomahub.liteflow.springboot.LiteflowProperty", + "defaultValue": false + }, + { + "name": "liteflow.rule-cache-capacity", "type": "java.lang.Integer", - "description": "Set the rules cache capacity.", + "description": "Set rule cache capacity.", "sourceType": "com.yomahub.liteflow.springboot.LiteflowProperty" } ] diff --git a/liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties b/liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties index 27b972e00..9a127bdc0 100644 --- a/liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties +++ b/liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties @@ -24,4 +24,5 @@ liteflow.global-thread-pool-size=16 liteflow.global-thread-pool-queue-size=512 liteflow.global-thread-pool-executor-class=com.yomahub.liteflow.thread.LiteFlowDefaultGlobalExecutorBuilder liteflow.enable-node-instance-id=false +liteflow.enable-rule-cache=false diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/application.properties b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/application.properties index 20fbd564f..069d7c7a1 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/application.properties +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/application.properties @@ -1,2 +1,3 @@ liteflow.rule-source=ruleCache/flow.el.xml +liteflow.enable-rule-cache=true liteflow.rule-cache-capacity=3 \ No newline at end of file From 73e4507b9d006b4513bb39140b51c79f864880fe Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Thu, 5 Dec 2024 23:33:37 +0800 Subject: [PATCH 09/34] =?UTF-8?q?feature=20#IAY66T=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=88=A4=E6=96=AD=E4=B8=8E=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/core/FlowExecutor.java | 34 ++++++++++++++----- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index 58bbec787..f48929a66 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -100,15 +100,6 @@ public class FlowExecutor { IdGeneratorHolder.init(); } - // 规则缓存 - if (isStart && liteflowConfig.getEnableRuleCache()) { - Integer capacity = liteflowConfig.getRuleCacheCapacity(); - RuleCacheLifeCycle ruleCacheLifeCycle = new RuleCacheLifeCycle(capacity); - LifeCycleHolder.addLifeCycle(ruleCacheLifeCycle); - // 执行时才解析chain - liteflowConfig.setParseMode(ParseModeEnum.PARSE_ONE_ON_FIRST_EXEC); - } - String ruleSource = liteflowConfig.getRuleSource(); if (StrUtil.isBlank(ruleSource)) { // 查看有没有Parser的SPI实现 @@ -235,6 +226,11 @@ public class FlowExecutor { } } + + // 规则缓存 + if (isStart && liteflowConfig.getEnableRuleCache()) { + initRuleCache(); + } } // 此方法就是从原有的配置源主动拉取新的进行刷新 @@ -643,4 +639,24 @@ public class FlowExecutor { return resultSlotList; } + + private void initRuleCache() { + // 容量不能小于等于0 + Integer capacity = liteflowConfig.getRuleCacheCapacity(); + if (ObjectUtil.isNull(capacity) || capacity <= 0) { + throw new ConfigErrorException("The rule cache capacity must be greater than 0"); + } + + // 容量不足chain总数的30%给予警告 + int chainNum = FlowBus.getChainMap().size(); + double threshold = chainNum * 0.3; + if (capacity < threshold) { + LOG.warn("The rule cache capacity is too small, it is recommended to be greater than 30% of the number of chains"); + } + + RuleCacheLifeCycle ruleCacheLifeCycle = new RuleCacheLifeCycle(capacity); + LifeCycleHolder.addLifeCycle(ruleCacheLifeCycle); + // 执行时才解析chain + liteflowConfig.setParseMode(ParseModeEnum.PARSE_ONE_ON_FIRST_EXEC); + } } \ No newline at end of file From b9ddc933844efc66bc124e31674d8b0efededadb Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Fri, 6 Dec 2024 21:40:42 +0800 Subject: [PATCH 10/34] =?UTF-8?q?feature=20#IAY66T=20=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=B9=B6=E5=8F=91=E4=B8=8BconditionList=E8=A2=AB=E6=B8=85?= =?UTF-8?q?=E9=99=A4=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/flow/element/Chain.java | 34 +++++++++++++++++-- .../lifecycle/impl/RuleCacheLifeCycle.java | 6 ++-- .../ruleCache/RuleCacheSpringbootTest.java | 15 ++++++++ 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java index 5c9577074..b9de1d41f 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java @@ -10,11 +10,13 @@ package com.yomahub.liteflow.flow.element; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.BooleanUtil; +import cn.hutool.core.util.IdUtil; import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder; import com.yomahub.liteflow.common.ChainConstant; import com.yomahub.liteflow.enums.ExecuteableTypeEnum; import com.yomahub.liteflow.exception.ChainEndException; import com.yomahub.liteflow.exception.FlowSystemException; +import com.yomahub.liteflow.flow.FlowBus; import com.yomahub.liteflow.lifecycle.LifeCycleHolder; import com.yomahub.liteflow.log.LFLog; import com.yomahub.liteflow.log.LFLoggerManager; @@ -29,6 +31,7 @@ import java.util.List; * * @author Bryan.Zhang * @author jason + * @author DaleLee */ public class Chain implements Executable{ @@ -100,8 +103,15 @@ public class Chain implements Executable{ LiteFlowChainELBuilder.buildUnCompileChain(this); } - if (CollUtil.isEmpty(conditionList)) { - throw new FlowSystemException("no conditionList in this chain[" + chainId + "]"); + // 这里先拿到this.conditionList的引用 + // 因为在正式执行condition之前,this.conditionList有可能被其他线程置空 + // 比如,该chain在规则缓存中被淘汰 + List conditionListRef = this.conditionList; + // 但在编译后到拿到引用之前,this.conditionList也有可能被置空 + if (CollUtil.isEmpty(conditionListRef)) { + // 如果conditionListRef为空, + // 构建临时conditionList确保本次一定可以执行 + conditionListRef = buildTemporaryConditionList(); } Slot slot = DataBus.getSlot(slotIndex); try { @@ -115,7 +125,7 @@ public class Chain implements Executable{ // 设置主ChainName slot.setChainId(chainId); // 执行主体Condition - for (Condition condition : conditionList) { + for (Condition condition : conditionListRef) { condition.setCurrChainId(chainId); condition.execute(slotIndex); } @@ -234,4 +244,22 @@ public class Chain implements Executable{ public void setThreadPoolExecutorClass(String threadPoolExecutorClass) { this.threadPoolExecutorClass = threadPoolExecutorClass; } + + // 构建临时的ConditionList + private List buildTemporaryConditionList() { + String tempChainId = chainId + "_temp_" + IdUtil.simpleUUID(); + Chain tempChain = new Chain(tempChainId); + tempChain.setEl(this.el); + tempChain.setCompiled(false); + LiteFlowChainELBuilder.buildUnCompileChain(tempChain); + FlowBus.removeChain(tempChainId); + + List tempConditionList = tempChain.getConditionList(); + if (CollUtil.isEmpty(tempConditionList)) { + throw new FlowSystemException("no conditionList in this chain[" + chainId + "]"); + } + // 打印警告,用于排查临时chain与已有chain重名(几乎不可能)而将已有chain覆盖的情况 + LOG.warn("The conditionList of chain[{}] is empty, temporarily using chain[{}] (now removed) to build it.", chainId, tempChainId); + return tempConditionList; + } } 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 db7b9be18..ac145184f 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 @@ -15,7 +15,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; /** * Chain执行前的缓存处理 * @author DaleLee - * @since + * @since 2.13.0 */ public class RuleCacheLifeCycle implements PostProcessFlowExecuteLifeCycle { // 缓存 @@ -61,9 +61,9 @@ public class RuleCacheLifeCycle implements PostProcessFlowExecuteLifeCycle { if (ObjectUtil.isNull(chain)) { return; } - // 清空condition并将chain设置为未编译 - chain.setConditionList(null); + // 将chain设置为未编译并清空condition chain.setCompiled(false); + chain.setConditionList(null); } } } 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 4a63b9a53..7a090632d 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 @@ -27,10 +27,13 @@ import java.util.HashSet; import java.util.List; import java.util.Random; import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; /** * Springboot环境下规则缓存测试 * @author DaleLee + * @since 2.13.0 */ @TestPropertySource(value = "classpath:/ruleCache/application.properties") @SpringBootTest(classes = RuleCacheSpringbootTest.class) @@ -129,6 +132,18 @@ public class RuleCacheSpringbootTest extends BaseTest { Assertions.assertEquals(ChainNotFoundException.class, response.getCause().getClass()); } + @Test + public void testRuleCache5() throws InterruptedException, ExecutionException { + Future liteflowResponseFuture = flowExecutor.execute2Future("chain1", "arg"); + new Thread(() -> { + flowExecutor.execute2Resp("chain2"); + flowExecutor.execute2Resp("chain3"); + flowExecutor.execute2Resp("chain4"); + }).start(); + + LiteflowResponse liteflowResponse = liteflowResponseFuture.get(); + } + // 加载缓存, chain1、chain2、chain3 private void loadCache() { From 598005b97de62758b5469469918c096cdeb4434d Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sat, 7 Dec 2024 21:02:00 +0800 Subject: [PATCH 11/34] =?UTF-8?q?feature=20#IAY66T=20=E5=AE=8C=E5=96=84Spr?= =?UTF-8?q?ingboot=E5=8D=95=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/core/FlowExecutor.java | 2 +- .../yomahub/liteflow/flow/element/Chain.java | 7 +- .../lifecycle/impl/RuleCacheLifeCycle.java | 14 ++- .../ruleCache/RuleCacheSpringbootTest.java | 89 +++++++++++-------- 4 files changed, 63 insertions(+), 49 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index f48929a66..ec1103e8d 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -651,7 +651,7 @@ public class FlowExecutor { int chainNum = FlowBus.getChainMap().size(); double threshold = chainNum * 0.3; if (capacity < threshold) { - LOG.warn("The rule cache capacity is too small, it is recommended to be greater than 30% of the number of chains"); + LOG.warn("The rule cache capacity {} is too small, it is recommended to be greater than 30% of the number of chains", capacity); } RuleCacheLifeCycle ruleCacheLifeCycle = new RuleCacheLifeCycle(capacity); diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java index b9de1d41f..0c68db8ee 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java @@ -247,18 +247,21 @@ public class Chain implements Executable{ // 构建临时的ConditionList private List buildTemporaryConditionList() { + // 构建临时chain String tempChainId = chainId + "_temp_" + IdUtil.simpleUUID(); Chain tempChain = new Chain(tempChainId); - tempChain.setEl(this.el); + tempChain.setEl(el); tempChain.setCompiled(false); LiteFlowChainELBuilder.buildUnCompileChain(tempChain); + // 移除临时chain FlowBus.removeChain(tempChainId); List tempConditionList = tempChain.getConditionList(); if (CollUtil.isEmpty(tempConditionList)) { throw new FlowSystemException("no conditionList in this chain[" + chainId + "]"); } - // 打印警告,用于排查临时chain与已有chain重名(几乎不可能)而将已有chain覆盖的情况 + + // 打印警告,可用于排查临时chain与已有chain重名(几乎不可能发生)而将已有chain覆盖的情况 LOG.warn("The conditionList of chain[{}] is empty, temporarily using chain[{}] (now removed) to build it.", chainId, tempChainId); return tempConditionList; } 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 ac145184f..0c45b4c1a 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 @@ -32,12 +32,10 @@ public class RuleCacheLifeCycle implements PostProcessFlowExecuteLifeCycle { @Override public void postProcessBeforeFlowExecute(String chainId, Slot slot) { - if (FlowBus.containChain(chainId)) { - // 记录chainId在缓存中 - // 这里不记录实际的chain是因为chain之后有可能在FlowBus中被移除 - // 或被更新,以FlowBus中实际存在的chain为准 - cache.put(chainId, PRESENT); - } + // 记录chainId在缓存中 + // 这里不记录实际的chain是因为chainId对应的chain之后有可能在FlowBus中被移除 + // 或被更新替换,以FlowBus中实际存在的chain为准 + cache.get(chainId, key -> PRESENT); } @Override @@ -61,9 +59,9 @@ public class RuleCacheLifeCycle implements PostProcessFlowExecuteLifeCycle { if (ObjectUtil.isNull(chain)) { return; } - // 将chain设置为未编译并清空condition - chain.setCompiled(false); + // 清空condition并将chain设置为未编译 chain.setConditionList(null); + chain.setCompiled(false); } } } 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 7a090632d..46ee9d1ed 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 @@ -27,8 +27,6 @@ import java.util.HashSet; import java.util.List; import java.util.Random; import java.util.Set; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; /** * Springboot环境下规则缓存测试 @@ -54,18 +52,20 @@ public class RuleCacheSpringbootTest extends BaseTest { // 测试chain被淘汰 @Test - public void testRuleCache1() throws InterruptedException { + public void testRuleCache1() { // 加满缓存 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()); // 获得被淘汰chain String chainId = getEvictedChain(strings); testEvicted(chainId); + // 测试被淘汰的chain仍可正常执行 + response = flowExecutor.execute2Resp(chainId, "arg"); + Assertions.assertTrue(response.isSuccess()); } // 测试缓存数量 @@ -91,37 +91,43 @@ public class RuleCacheSpringbootTest extends BaseTest { Assertions.assertEquals(3, count); } - // 测试chain被更新 + // 测试开启规则缓存后,进入缓存的chain可以正常被更新 @Test - public void testRuleCache3() throws InterruptedException { - loadCache(); - // 缓存快照 - HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); - flowExecutor.execute2Resp("chain5", "arg"); - // 获得被淘汰chain - String chainId = getEvictedChain(strings); - testEvicted(chainId); - // 更新chain1 - LiteFlowChainELBuilder - .createChain() - .setChainId("chain1") - .setEL("THEN(a, b, c)") - .build(); - // 重新执行chain1 - LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); - Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("a==>b==>c", response.getExecuteStepStr()); - } - - // 测试chain被移除 - @Test - public void testRuleCache4() throws InterruptedException { + public void testRuleCache3() { 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()); + // chain5进入缓存 + Assertions.assertTrue(getCache().asMap().containsKey("chain5")); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); + // 更新chain5 + LiteFlowChainELBuilder + .createChain() + .setChainId("chain5") + .setEL("THEN(a, b, c)") + .build(); + // 重新执行chain5 + response = flowExecutor.execute2Resp("chain5", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("a==>b==>c", response.getExecuteStepStr()); + } + + // 测试开启规则缓存后,进入缓存的chain被移除后无法执行 + @Test + public void testRuleCache4() { + 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()); + // chain5进入缓存 + Assertions.assertTrue(getCache().asMap().containsKey("chain5")); // 获得被淘汰chain String chainId = getEvictedChain(strings); testEvicted(chainId); @@ -132,16 +138,20 @@ public class RuleCacheSpringbootTest extends BaseTest { Assertions.assertEquals(ChainNotFoundException.class, response.getCause().getClass()); } + // 测试并发下,正在执行的chain被淘汰仍能执行 @Test - public void testRuleCache5() throws InterruptedException, ExecutionException { - Future liteflowResponseFuture = flowExecutor.execute2Future("chain1", "arg"); - new Thread(() -> { - flowExecutor.execute2Resp("chain2"); - flowExecutor.execute2Resp("chain3"); - flowExecutor.execute2Resp("chain4"); - }).start(); - - LiteflowResponse liteflowResponse = liteflowResponseFuture.get(); + public void testRuleCache5() throws InterruptedException { + // 模拟清空编译好的chain + Thread thread = new Thread(()-> { + Chain chain1 = FlowBus.getChain("chain1"); + chain1.setCompiled(true); + chain1.setConditionList(null); + }); + thread.start(); + thread.join(); + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("a==>b", response.getExecuteStepStr()); } @@ -169,9 +179,12 @@ public class RuleCacheSpringbootTest extends BaseTest { } // 测试 chain 被淘汰 - private void testEvicted(String chanId) throws InterruptedException { + private void testEvicted(String chanId) { Chain chain = FlowBus.getChain(chanId); getCache().cleanUp(); + // 测试缓存中不存在 + Assertions.assertFalse(getCache().asMap().containsKey(chanId)); + // 测试chain被设置为未编译 Assertions.assertFalse(chain.isCompiled()); Assertions.assertNull(chain.getConditionList()); } From 553e542d114572077bc7bbcbb1b0b5dd2f5781b8 Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sat, 7 Dec 2024 21:48:01 +0800 Subject: [PATCH 12/34] =?UTF-8?q?feature=20#IAY66T=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=9D=9ESpring=E7=8E=AF=E5=A2=83=E5=8D=95=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/ruleCache/RuleCacheTest.java | 212 ++++++++++++++++++ .../liteflow/test/ruleCache/cmp/ACmp.java | 18 ++ .../liteflow/test/ruleCache/cmp/BCmp.java | 19 ++ .../liteflow/test/ruleCache/cmp/CCmp.java | 18 ++ .../liteflow/test/ruleCache/cmp/XCmp.java | 10 + .../src/test/resources/ruleCache/flow.el.xml | 50 +++++ .../ruleCache/RuleCacheSpringbootTest.java | 58 +++-- .../ruleCache/application.properties | 2 +- .../src/test/resources/ruleCache/flow.el.xml | 24 +- 9 files changed, 376 insertions(+), 35 deletions(-) create mode 100644 liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/ruleCache/flow.el.xml diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java new file mode 100644 index 000000000..32524ac58 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java @@ -0,0 +1,212 @@ +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.core.FlowExecutorHolder; +import com.yomahub.liteflow.exception.ChainNotFoundException; +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.property.LiteflowConfig; +import com.yomahub.liteflow.test.BaseTest; +import org.checkerframework.checker.nullness.qual.NonNull; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.HashSet; +import java.util.List; +import java.util.Random; +import java.util.Set; + +/** + * 非Spring环境下的规则缓存测试 + * @author DaleLee + * @since 2.13.0 + */ +public class RuleCacheTest extends BaseTest { + + private static FlowExecutor flowExecutor; + + @BeforeAll + public static void init() { + LiteflowConfig config = new LiteflowConfig(); + config.setRuleSource("ruleCache/flow.el.xml"); + config.setEnableRuleCache(true); + config.setRuleCacheCapacity(5); + flowExecutor = FlowExecutorHolder.loadInstance(config); + } + + @BeforeEach + public void reload() { + flowExecutor.reloadRule(); + // 清空缓存 + Cache cache = getCache(); + cache.invalidateAll(); + cache.cleanUp(); + } + + // 测试chain被淘汰 + @Test + public void testRuleCache1() { + // 加满缓存 + loadCache(); + // 缓存快照 + HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); + LiteflowResponse response = flowExecutor.execute2Resp("chain6", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("c==>b", response.getExecuteStepStr()); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); + // 测试被淘汰的chain仍可正常执行 + response = flowExecutor.execute2Resp(chainId, "arg"); + Assertions.assertTrue(response.isSuccess()); + } + + // 测试缓存数量 + @Test + public void testRuleCache2() { + // 确保至少执行过5个不同的chain + loadCache(); + // 随机执行chain + loadCache(100); + // 等待缓存淘汰 + getCache().cleanUp(); + // 测试只有5个chain被编译 + int count = 0; + for (Chain chain : FlowBus.getChainMap().values()) { + List conditionList = chain.getConditionList(); + if (chain.isCompiled()) { + Assertions.assertTrue(CollUtil.isNotEmpty(conditionList)); + count++; + } else { + Assertions.assertNull(conditionList); + } + } + Assertions.assertEquals(5, count); + } + + // 测试开启规则缓存后,进入缓存的chain可以正常被更新 + @Test + public void testRuleCache3() { + loadCache(); + // 缓存快照 + HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); + LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); + // chain7进入缓存 + Assertions.assertTrue(getCache().asMap().containsKey("chain7")); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); + // 更新chain7 + LiteFlowChainELBuilder + .createChain() + .setChainId("chain7") + .setEL("THEN(a, b, c)") + .build(); + // 重新执行chain7 + response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("a==>b==>c", response.getExecuteStepStr()); + } + + // 测试开启规则缓存后,进入缓存的chain被移除后无法执行 + @Test + public void testRuleCache4() { + loadCache(); + // 缓存快照 + HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); + LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); + // chain7进入缓存 + Assertions.assertTrue(getCache().asMap().containsKey("chain7")); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); + // 手动移除chain7 + FlowBus.removeChain("chain7"); + response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertFalse(response.isSuccess()); + Assertions.assertEquals(ChainNotFoundException.class, response.getCause().getClass()); + } + + // 测试并发下,正在执行的chain被淘汰仍能执行 + @Test + public void testRuleCache5() throws InterruptedException { + // 模拟清空编译好的chain + Thread thread = new Thread(()-> { + Chain chain1 = FlowBus.getChain("chain1"); + chain1.setCompiled(true); + chain1.setConditionList(null); + }); + thread.start(); + thread.join(); + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("a==>b", response.getExecuteStepStr()); + } + + + // 加载缓存, chain1~chain5 + private void loadCache() { + // 容量上限为5 + for (int i = 1; i <= 5; i++) { + flowExecutor.execute2Resp("chain" + i); + } + } + + private void loadCache(int count) { + // 随机执行chain + Random random = new Random(); + for (int i = 0; i < count; i++) { + int id = random.nextInt(10) + 1; + flowExecutor.execute2Resp("chain" + id); + } + } + + // 测试 chain 被淘汰 + private void testEvicted(String chanId) { + Chain chain = FlowBus.getChain(chanId); + getCache().cleanUp(); + // 测试缓存中不存在 + Assertions.assertFalse(getCache().asMap().containsKey(chanId)); + // 测试chain被设置为未编译 + 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(); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java new file mode 100644 index 000000000..1681cc291 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java @@ -0,0 +1,18 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.ruleCache.cmp; + +import com.yomahub.liteflow.core.NodeComponent; + +public class ACmp extends NodeComponent { + + @Override + public void process() { + System.out.println("ACmp executed!"); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java new file mode 100644 index 000000000..af5a966ab --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java @@ -0,0 +1,19 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.ruleCache.cmp; + +import com.yomahub.liteflow.core.NodeComponent; + +public class BCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("BCmp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java new file mode 100644 index 000000000..b64d73f1b --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java @@ -0,0 +1,18 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.ruleCache.cmp; + +import com.yomahub.liteflow.core.NodeComponent; + +public class CCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("CCmp executed!"); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java new file mode 100644 index 000000000..61e48503d --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java @@ -0,0 +1,10 @@ +package com.yomahub.liteflow.test.ruleCache.cmp; + +import com.yomahub.liteflow.core.NodeBooleanComponent; + +public class XCmp extends NodeBooleanComponent { + @Override + public boolean processBoolean() throws Exception { + return true; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/ruleCache/flow.el.xml b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/ruleCache/flow.el.xml new file mode 100644 index 000000000..5bfd951f8 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/ruleCache/flow.el.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + THEN(a, b); + + + + THEN(a, c); + + + + THEN(b, a); + + + + THEN(b, c); + + + + THEN(c, a); + + + + THEN(c, b); + + + + THEN(IF(x, a), b); + + + + THEN(IF(x, a), c); + + + + WHEN(a, b, c); + + + + FOR(5).DO(THEN(a, b, c)); + + + \ No newline at end of file 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 46ee9d1ed..69ea52ebc 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 @@ -57,9 +57,9 @@ public class RuleCacheSpringbootTest extends BaseTest { loadCache(); // 缓存快照 HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); - LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg"); + LiteflowResponse response = flowExecutor.execute2Resp("chain6", "arg"); Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); + Assertions.assertEquals("c==>b", response.getExecuteStepStr()); // 获得被淘汰chain String chainId = getEvictedChain(strings); testEvicted(chainId); @@ -71,13 +71,13 @@ public class RuleCacheSpringbootTest extends BaseTest { // 测试缓存数量 @Test public void testRuleCache2() { - // 确保至少执行过3个不同的chain + // 确保至少执行过5个不同的chain loadCache(); // 随机执行chain loadCache(100); // 等待缓存淘汰 getCache().cleanUp(); - // 测试只有3个chain被编译 + // 测试只有5个chain被编译 int count = 0; for (Chain chain : FlowBus.getChainMap().values()) { List conditionList = chain.getConditionList(); @@ -88,7 +88,7 @@ public class RuleCacheSpringbootTest extends BaseTest { Assertions.assertNull(conditionList); } } - Assertions.assertEquals(3, count); + Assertions.assertEquals(5, count); } // 测试开启规则缓存后,进入缓存的chain可以正常被更新 @@ -97,22 +97,22 @@ public class RuleCacheSpringbootTest extends BaseTest { loadCache(); // 缓存快照 HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); - LiteflowResponse response = flowExecutor.execute2Resp("chain5", "arg"); + LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("x==>a==>c", response.getExecuteStepStr()); - // chain5进入缓存 - Assertions.assertTrue(getCache().asMap().containsKey("chain5")); + Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); + // chain7进入缓存 + Assertions.assertTrue(getCache().asMap().containsKey("chain7")); // 获得被淘汰chain String chainId = getEvictedChain(strings); testEvicted(chainId); - // 更新chain5 + // 更新chain7 LiteFlowChainELBuilder .createChain() - .setChainId("chain5") + .setChainId("chain7") .setEL("THEN(a, b, c)") .build(); - // 重新执行chain5 - response = flowExecutor.execute2Resp("chain5", "arg"); + // 重新执行chain7 + response = flowExecutor.execute2Resp("chain7", "arg"); Assertions.assertTrue(response.isSuccess()); Assertions.assertEquals("a==>b==>c", response.getExecuteStepStr()); } @@ -123,17 +123,17 @@ public class RuleCacheSpringbootTest extends BaseTest { loadCache(); // 缓存快照 HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); - LiteflowResponse response = flowExecutor.execute2Resp("chain5", "arg"); + LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("x==>a==>c", response.getExecuteStepStr()); - // chain5进入缓存 - Assertions.assertTrue(getCache().asMap().containsKey("chain5")); + Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); + // chain7进入缓存 + Assertions.assertTrue(getCache().asMap().containsKey("chain7")); // 获得被淘汰chain String chainId = getEvictedChain(strings); testEvicted(chainId); - // 手动移除chain5 - FlowBus.removeChain("chain5"); - response = flowExecutor.execute2Resp("chain5", "arg"); + // 手动移除chain7 + FlowBus.removeChain("chain7"); + response = flowExecutor.execute2Resp("chain7", "arg"); Assertions.assertFalse(response.isSuccess()); Assertions.assertEquals(ChainNotFoundException.class, response.getCause().getClass()); } @@ -155,25 +155,19 @@ public class RuleCacheSpringbootTest extends BaseTest { } - // 加载缓存, chain1、chain2、chain3 + // 加载缓存, chain1~chain5 private void loadCache() { - // 容量上限为3 - LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); - Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("a==>b", response.getExecuteStepStr()); - response = flowExecutor.execute2Resp("chain2", "arg"); - Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("a==>c", response.getExecuteStepStr()); - response = flowExecutor.execute2Resp("chain3", "arg"); - Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("b==>c", response.getExecuteStepStr()); + // 容量上限为5 + for (int i = 1; i <= 5; i++) { + flowExecutor.execute2Resp("chain" + i); + } } private void loadCache(int count) { // 随机执行chain Random random = new Random(); for (int i = 0; i < count; i++) { - int id = random.nextInt(5) + 1; + int id = random.nextInt(10) + 1; flowExecutor.execute2Resp("chain" + id); } } diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/application.properties b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/application.properties index 069d7c7a1..36277b504 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/application.properties +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/application.properties @@ -1,3 +1,3 @@ liteflow.rule-source=ruleCache/flow.el.xml liteflow.enable-rule-cache=true -liteflow.rule-cache-capacity=3 \ No newline at end of file +liteflow.rule-cache-capacity=5 \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/flow.el.xml b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/flow.el.xml index 08df154be..11acd1cd4 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/flow.el.xml +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/flow.el.xml @@ -9,15 +9,35 @@
- THEN(b, c); + THEN(b, a); - THEN(IF(x, a), b); + THEN(b, c); + THEN(c, a); + + + + THEN(c, b); + + + + THEN(IF(x, a), b); + + + THEN(IF(x, a), c); + + WHEN(a, b, c); + + + + FOR(5).DO(THEN(a, b, c)); + + \ No newline at end of file From a4f8efd4354ca4383b9be134d526023cf8345d81 Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sat, 7 Dec 2024 23:27:53 +0800 Subject: [PATCH 13/34] =?UTF-8?q?feature=20#IAY66T=20=E4=BF=AE=E6=94=B9Spr?= =?UTF-8?q?ingboot=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../liteflow/springboot/LiteflowProperty.java | 47 ++++++++++++------- .../LiteflowPropertyAutoConfiguration.java | 4 +- ...itional-spring-configuration-metadata.json | 4 +- .../META-INF/liteflow-default.properties | 2 +- .../ruleCache/application.properties | 4 +- 5 files changed, 38 insertions(+), 23 deletions(-) diff --git a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java index 8b7cdc12e..bea2a0d4b 100644 --- a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java +++ b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java @@ -4,6 +4,7 @@ import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.yomahub.liteflow.enums.ParseModeEnum; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.context.properties.NestedConfigurationProperty; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -99,11 +100,33 @@ public class LiteflowProperty { //是否启用节点实例ID private boolean enableNodeInstanceId; - // 是否启用规则缓存 - private Boolean enableRuleCache; + // 规则缓存配置 + @NestedConfigurationProperty + private RuleCache ruleCache; - // 规则缓存容量 - private Integer ruleCacheCapacity; + public static class RuleCache { + // 是否启用规则缓存 + private Boolean enabled; + + // 规则缓存容量 + private Integer capacity; + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public Integer getCapacity() { + return capacity; + } + + public void setCapacity(Integer capacity) { + this.capacity = capacity; + } + } public boolean isEnableMonitorFile() { return enableMonitorFile; @@ -337,19 +360,11 @@ public class LiteflowProperty { this.enableNodeInstanceId = enableNodeInstanceId; } - public Integer getRuleCacheCapacity() { - return ruleCacheCapacity; + public RuleCache getRuleCache() { + return ruleCache; } - public void setRuleCacheCapacity(Integer ruleCacheCapacity) { - this.ruleCacheCapacity = ruleCacheCapacity; - } - - public Boolean isEnableRuleCache() { - return enableRuleCache; - } - - public void setEnableRuleCache(Boolean enableRuleCache) { - this.enableRuleCache = enableRuleCache; + public void setRuleCache(RuleCache ruleCache) { + this.ruleCache = ruleCache; } } diff --git a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java index e4b9c4f50..01b9e1afc 100644 --- a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java +++ b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java @@ -53,8 +53,8 @@ public class LiteflowPropertyAutoConfiguration { liteflowConfig.setGlobalThreadPoolQueueSize(property.getGlobalThreadPoolQueueSize()); liteflowConfig.setGlobalThreadPoolSize(property.getGlobalThreadPoolSize()); liteflowConfig.setEnableNodeInstanceId(property.isEnableNodeInstanceId()); - liteflowConfig.setEnableRuleCache(property.isEnableRuleCache()); - liteflowConfig.setRuleCacheCapacity(property.getRuleCacheCapacity()); + liteflowConfig.setEnableRuleCache(property.getRuleCache().getEnabled()); + liteflowConfig.setRuleCacheCapacity(property.getRuleCache().getCapacity()); return liteflowConfig; } diff --git a/liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 89cb4d599..615533078 100644 --- a/liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/liteflow-spring-boot-starter/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -208,14 +208,14 @@ "defaultValue": false }, { - "name": "liteflow.enable-rule-cache", + "name": "liteflow.rule-cache.enabled", "type": "java.lang.Boolean", "description": "Enable rule cache.", "sourceType": "com.yomahub.liteflow.springboot.LiteflowProperty", "defaultValue": false }, { - "name": "liteflow.rule-cache-capacity", + "name": "liteflow.rule-cache.capacity", "type": "java.lang.Integer", "description": "Set rule cache capacity.", "sourceType": "com.yomahub.liteflow.springboot.LiteflowProperty" diff --git a/liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties b/liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties index 9a127bdc0..0be2968a8 100644 --- a/liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties +++ b/liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties @@ -24,5 +24,5 @@ liteflow.global-thread-pool-size=16 liteflow.global-thread-pool-queue-size=512 liteflow.global-thread-pool-executor-class=com.yomahub.liteflow.thread.LiteFlowDefaultGlobalExecutorBuilder liteflow.enable-node-instance-id=false -liteflow.enable-rule-cache=false +liteflow.rule-cache.enabled=false diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/application.properties b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/application.properties index 36277b504..cb4066d3c 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/application.properties +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/application.properties @@ -1,3 +1,3 @@ liteflow.rule-source=ruleCache/flow.el.xml -liteflow.enable-rule-cache=true -liteflow.rule-cache-capacity=5 \ No newline at end of file +liteflow.rule-cache.enabled=true +liteflow.rule-cache.capacity=5 \ No newline at end of file From 8410b4ee489f7f3b06904c17713c023fd663a7ee Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sat, 7 Dec 2024 23:54:25 +0800 Subject: [PATCH 14/34] =?UTF-8?q?feature=20#IAY66T=20=E6=B7=BB=E5=8A=A0Sol?= =?UTF-8?q?on=E7=8E=AF=E5=A2=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/LiteflowAutoConfiguration.java | 2 + .../solon/config/LiteflowProperty.java | 35 +++ .../META-INF/liteflow-default.properties | 1 + .../test/ruleCache/RuleCacheSolonTest.java | 206 ++++++++++++++++++ .../liteflow/test/ruleCache/cmp/ACmp.java | 20 ++ .../liteflow/test/ruleCache/cmp/BCmp.java | 21 ++ .../liteflow/test/ruleCache/cmp/CCmp.java | 20 ++ .../liteflow/test/ruleCache/cmp/XCmp.java | 12 + .../ruleCache/application.properties | 3 + .../src/test/resources/ruleCache/flow.el.xml | 43 ++++ 10 files changed, 363 insertions(+) create mode 100644 liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/ruleCache/application.properties create mode 100644 liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/ruleCache/flow.el.xml diff --git a/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowAutoConfiguration.java b/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowAutoConfiguration.java index f0e81d247..c14d4c11e 100644 --- a/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowAutoConfiguration.java +++ b/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowAutoConfiguration.java @@ -51,6 +51,8 @@ public class LiteflowAutoConfiguration { liteflowConfig.setGlobalThreadPoolQueueSize(property.getGlobalThreadPoolQueueSize()); liteflowConfig.setWhenThreadPoolIsolate(property.getWhenThreadPoolIsolate()); liteflowConfig.setEnableNodeInstanceId(property.isEnableNodeInstanceId()); + liteflowConfig.setEnableRuleCache(property.getRuleCache().getEnabled()); + liteflowConfig.setRuleCacheCapacity(property.getRuleCache().getCapacity()); return liteflowConfig; } diff --git a/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowProperty.java b/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowProperty.java index cca6b3542..1319a8d1a 100644 --- a/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowProperty.java +++ b/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowProperty.java @@ -101,6 +101,33 @@ public class LiteflowProperty { //是否启用节点实例ID private boolean enableNodeInstanceId; + // 规则缓存配置 + private RuleCache ruleCache; + + public static class RuleCache { + // 是否启用规则缓存 + private Boolean enabled; + + // 规则缓存容量 + private Integer capacity; + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public Integer getCapacity() { + return capacity; + } + + public void setCapacity(Integer capacity) { + this.capacity = capacity; + } + } + public boolean isEnable() { return enable; } @@ -341,4 +368,12 @@ public class LiteflowProperty { public void setEnableNodeInstanceId(boolean enableNodeInstanceId) { this.enableNodeInstanceId = enableNodeInstanceId; } + + public RuleCache getRuleCache() { + return ruleCache; + } + + public void setRuleCache(RuleCache ruleCache) { + this.ruleCache = ruleCache; + } } diff --git a/liteflow-solon-plugin/src/main/resources/META-INF/liteflow-default.properties b/liteflow-solon-plugin/src/main/resources/META-INF/liteflow-default.properties index c3dbf73d5..c3ef43c84 100644 --- a/liteflow-solon-plugin/src/main/resources/META-INF/liteflow-default.properties +++ b/liteflow-solon-plugin/src/main/resources/META-INF/liteflow-default.properties @@ -19,3 +19,4 @@ liteflow.global-thread-pool-size=16 liteflow.global-thread-pool-queue-size=512 liteflow.global-thread-pool-executor-class=com.yomahub.liteflow.thread.LiteFlowDefaultGlobalExecutorBuilder liteflow.enable-node-instance-id=true +liteflow.rule-cache.enabled=false diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java new file mode 100644 index 000000000..1defd6013 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java @@ -0,0 +1,206 @@ +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; +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.noear.solon.annotation.Import; +import org.noear.solon.annotation.Inject; +import org.noear.solon.test.SolonTest; +import org.springframework.test.context.TestPropertySource; + +import java.util.HashSet; +import java.util.List; +import java.util.Random; +import java.util.Set; + +/** + * Solon环境下规则缓存测试 + * @author DaleLee + * @since 2.13.0 + */ +@SolonTest +@Import(profiles="classpath:/ruleCache/application.properties") +public class RuleCacheSolonTest extends BaseTest { + + @Inject + private FlowExecutor flowExecutor; + + @BeforeEach + public void reload() { + flowExecutor.reloadRule(); + // 清空缓存 + Cache cache = getCache(); + cache.invalidateAll(); + cache.cleanUp(); + } + + // 测试chain被淘汰 + @Test + public void testRuleCache1() { + // 加满缓存 + loadCache(); + // 缓存快照 + HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); + LiteflowResponse response = flowExecutor.execute2Resp("chain6", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("c==>b", response.getExecuteStepStr()); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); + // 测试被淘汰的chain仍可正常执行 + response = flowExecutor.execute2Resp(chainId, "arg"); + Assertions.assertTrue(response.isSuccess()); + } + + // 测试缓存数量 + @Test + public void testRuleCache2() { + // 确保至少执行过5个不同的chain + loadCache(); + // 随机执行chain + loadCache(100); + // 等待缓存淘汰 + getCache().cleanUp(); + // 测试只有5个chain被编译 + int count = 0; + for (Chain chain : FlowBus.getChainMap().values()) { + List conditionList = chain.getConditionList(); + if (chain.isCompiled()) { + Assertions.assertTrue(CollUtil.isNotEmpty(conditionList)); + count++; + } else { + Assertions.assertNull(conditionList); + } + } + Assertions.assertEquals(5, count); + } + + // 测试开启规则缓存后,进入缓存的chain可以正常被更新 + @Test + public void testRuleCache3() { + loadCache(); + // 缓存快照 + HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); + LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); + // chain7进入缓存 + Assertions.assertTrue(getCache().asMap().containsKey("chain7")); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); + // 更新chain7 + LiteFlowChainELBuilder + .createChain() + .setChainId("chain7") + .setEL("THEN(a, b, c)") + .build(); + // 重新执行chain7 + response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("a==>b==>c", response.getExecuteStepStr()); + } + + // 测试开启规则缓存后,进入缓存的chain被移除后无法执行 + @Test + public void testRuleCache4() { + loadCache(); + // 缓存快照 + HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); + LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); + // chain7进入缓存 + Assertions.assertTrue(getCache().asMap().containsKey("chain7")); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); + // 手动移除chain7 + FlowBus.removeChain("chain7"); + response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertFalse(response.isSuccess()); + Assertions.assertEquals(ChainNotFoundException.class, response.getCause().getClass()); + } + + // 测试并发下,正在执行的chain被淘汰仍能执行 + @Test + public void testRuleCache5() throws InterruptedException { + // 模拟清空编译好的chain + Thread thread = new Thread(()-> { + Chain chain1 = FlowBus.getChain("chain1"); + chain1.setCompiled(true); + chain1.setConditionList(null); + }); + thread.start(); + thread.join(); + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("a==>b", response.getExecuteStepStr()); + } + + + // 加载缓存, chain1~chain5 + private void loadCache() { + // 容量上限为5 + for (int i = 1; i <= 5; i++) { + flowExecutor.execute2Resp("chain" + i); + } + } + + private void loadCache(int count) { + // 随机执行chain + Random random = new Random(); + for (int i = 0; i < count; i++) { + int id = random.nextInt(10) + 1; + flowExecutor.execute2Resp("chain" + id); + } + } + + // 测试 chain 被淘汰 + private void testEvicted(String chanId) { + Chain chain = FlowBus.getChain(chanId); + getCache().cleanUp(); + // 测试缓存中不存在 + Assertions.assertFalse(getCache().asMap().containsKey(chanId)); + // 测试chain被设置为未编译 + 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(); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java new file mode 100644 index 000000000..da4be1512 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java @@ -0,0 +1,20 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.ruleCache.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.noear.solon.annotation.Component; + +@Component("a") +public class ACmp extends NodeComponent { + + @Override + public void process() { + System.out.println("ACmp executed!"); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java new file mode 100644 index 000000000..7f957f293 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java @@ -0,0 +1,21 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.ruleCache.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.noear.solon.annotation.Component; + +@Component("b") +public class BCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("BCmp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java new file mode 100644 index 000000000..c49a987e9 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java @@ -0,0 +1,20 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.ruleCache.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.noear.solon.annotation.Component; + +@Component("c") +public class CCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("CCmp executed!"); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java new file mode 100644 index 000000000..73b375e01 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java @@ -0,0 +1,12 @@ +package com.yomahub.liteflow.test.ruleCache.cmp; + +import com.yomahub.liteflow.core.NodeBooleanComponent; +import org.noear.solon.annotation.Component; + +@Component("x") +public class XCmp extends NodeBooleanComponent { + @Override + public boolean processBoolean() throws Exception { + return true; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/ruleCache/application.properties b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/ruleCache/application.properties new file mode 100644 index 000000000..cb4066d3c --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/ruleCache/application.properties @@ -0,0 +1,3 @@ +liteflow.rule-source=ruleCache/flow.el.xml +liteflow.rule-cache.enabled=true +liteflow.rule-cache.capacity=5 \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/ruleCache/flow.el.xml b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/ruleCache/flow.el.xml new file mode 100644 index 000000000..11acd1cd4 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/ruleCache/flow.el.xml @@ -0,0 +1,43 @@ + + + + THEN(a, b); + + + + THEN(a, c); + + + + THEN(b, a); + + + + THEN(b, c); + + + + THEN(c, a); + + + + THEN(c, b); + + + + THEN(IF(x, a), b); + + + + THEN(IF(x, a), c); + + + + WHEN(a, b, c); + + + + FOR(5).DO(THEN(a, b, c)); + + + \ No newline at end of file From a7514388b60c6122ae6bef96cdbc7fcf08cb9682 Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sun, 8 Dec 2024 00:11:34 +0800 Subject: [PATCH 15/34] =?UTF-8?q?feature=20#IAY66T=20=E6=B7=BB=E5=8A=A0Spr?= =?UTF-8?q?ing=E7=8E=AF=E5=A2=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../test/ruleCache/RuleCacheSpringTest.java | 205 ++++++++++++++++++ .../liteflow/test/ruleCache/cmp/ACmp.java | 20 ++ .../liteflow/test/ruleCache/cmp/BCmp.java | 21 ++ .../liteflow/test/ruleCache/cmp/CCmp.java | 20 ++ .../liteflow/test/ruleCache/cmp/XCmp.java | 12 + .../test/resources/ruleCache/application.xml | 25 +++ .../src/test/resources/ruleCache/flow.el.xml | 43 ++++ 7 files changed, 346 insertions(+) create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/ruleCache/application.xml create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/ruleCache/flow.el.xml diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java new file mode 100644 index 000000000..41ca4d553 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java @@ -0,0 +1,205 @@ +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; +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.junit.jupiter.api.extension.ExtendWith; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import javax.annotation.Resource; +import java.util.HashSet; +import java.util.List; +import java.util.Random; +import java.util.Set; + +/** + * Spring环境下规则缓存测试 + * @author DaleLee + * @since 2.13.0 + */ +@ExtendWith(SpringExtension.class) +@ContextConfiguration("classpath:/ruleCache/application.xml") +public class RuleCacheSpringTest extends BaseTest { + @Resource + private FlowExecutor flowExecutor; + + @BeforeEach + public void reload() { + flowExecutor.reloadRule(); + // 清空缓存 + Cache cache = getCache(); + cache.invalidateAll(); + cache.cleanUp(); + } + + // 测试chain被淘汰 + @Test + public void testRuleCache1() { + // 加满缓存 + loadCache(); + // 缓存快照 + HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); + LiteflowResponse response = flowExecutor.execute2Resp("chain6", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("c==>b", response.getExecuteStepStr()); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); + // 测试被淘汰的chain仍可正常执行 + response = flowExecutor.execute2Resp(chainId, "arg"); + Assertions.assertTrue(response.isSuccess()); + } + + // 测试缓存数量 + @Test + public void testRuleCache2() { + // 确保至少执行过5个不同的chain + loadCache(); + // 随机执行chain + loadCache(100); + // 等待缓存淘汰 + getCache().cleanUp(); + // 测试只有5个chain被编译 + int count = 0; + for (Chain chain : FlowBus.getChainMap().values()) { + List conditionList = chain.getConditionList(); + if (chain.isCompiled()) { + Assertions.assertTrue(CollUtil.isNotEmpty(conditionList)); + count++; + } else { + Assertions.assertNull(conditionList); + } + } + Assertions.assertEquals(5, count); + } + + // 测试开启规则缓存后,进入缓存的chain可以正常被更新 + @Test + public void testRuleCache3() { + loadCache(); + // 缓存快照 + HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); + LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); + // chain7进入缓存 + Assertions.assertTrue(getCache().asMap().containsKey("chain7")); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); + // 更新chain7 + LiteFlowChainELBuilder + .createChain() + .setChainId("chain7") + .setEL("THEN(a, b, c)") + .build(); + // 重新执行chain7 + response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("a==>b==>c", response.getExecuteStepStr()); + } + + // 测试开启规则缓存后,进入缓存的chain被移除后无法执行 + @Test + public void testRuleCache4() { + loadCache(); + // 缓存快照 + HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); + LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); + // chain7进入缓存 + Assertions.assertTrue(getCache().asMap().containsKey("chain7")); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); + // 手动移除chain7 + FlowBus.removeChain("chain7"); + response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertFalse(response.isSuccess()); + Assertions.assertEquals(ChainNotFoundException.class, response.getCause().getClass()); + } + + // 测试并发下,正在执行的chain被淘汰仍能执行 + @Test + public void testRuleCache5() throws InterruptedException { + // 模拟清空编译好的chain + Thread thread = new Thread(()-> { + Chain chain1 = FlowBus.getChain("chain1"); + chain1.setCompiled(true); + chain1.setConditionList(null); + }); + thread.start(); + thread.join(); + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("a==>b", response.getExecuteStepStr()); + } + + + // 加载缓存, chain1~chain5 + private void loadCache() { + // 容量上限为5 + for (int i = 1; i <= 5; i++) { + flowExecutor.execute2Resp("chain" + i); + } + } + + private void loadCache(int count) { + // 随机执行chain + Random random = new Random(); + for (int i = 0; i < count; i++) { + int id = random.nextInt(10) + 1; + flowExecutor.execute2Resp("chain" + id); + } + } + + // 测试 chain 被淘汰 + private void testEvicted(String chanId) { + Chain chain = FlowBus.getChain(chanId); + getCache().cleanUp(); + // 测试缓存中不存在 + Assertions.assertFalse(getCache().asMap().containsKey(chanId)); + // 测试chain被设置为未编译 + 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(); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java new file mode 100644 index 000000000..e5999686e --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java @@ -0,0 +1,20 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.ruleCache.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("a") +public class ACmp extends NodeComponent { + + @Override + public void process() { + System.out.println("ACmp executed!"); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java new file mode 100644 index 000000000..c79f55d47 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java @@ -0,0 +1,21 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.ruleCache.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("b") +public class BCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("BCmp executed!"); + } + +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java new file mode 100644 index 000000000..a5ba32f37 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java @@ -0,0 +1,20 @@ +/** + *

Title: liteflow

+ *

Description: 轻量级的组件式流程框架

+ * @author Bryan.Zhang + * @email weenyc31@163.com + * @Date 2020/4/1 + */ +package com.yomahub.liteflow.test.ruleCache.cmp; + +import com.yomahub.liteflow.core.NodeComponent; +import org.springframework.stereotype.Component; + +@Component("c") +public class CCmp extends NodeComponent { + + @Override + public void process() { + System.out.println("CCmp executed!"); + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java new file mode 100644 index 000000000..1c71b836c --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java @@ -0,0 +1,12 @@ +package com.yomahub.liteflow.test.ruleCache.cmp; + +import com.yomahub.liteflow.core.NodeBooleanComponent; +import org.springframework.stereotype.Component; + +@Component("x") +public class XCmp extends NodeBooleanComponent { + @Override + public boolean processBoolean() throws Exception { + return true; + } +} diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/ruleCache/application.xml b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/ruleCache/application.xml new file mode 100644 index 000000000..278b241f5 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/ruleCache/application.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/ruleCache/flow.el.xml b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/ruleCache/flow.el.xml new file mode 100644 index 000000000..11acd1cd4 --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/ruleCache/flow.el.xml @@ -0,0 +1,43 @@ + + + + THEN(a, b); + + + + THEN(a, c); + + + + THEN(b, a); + + + + THEN(b, c); + + + + THEN(c, a); + + + + THEN(c, b); + + + + THEN(IF(x, a), b); + + + + THEN(IF(x, a), c); + + + + WHEN(a, b, c); + + + + FOR(5).DO(THEN(a, b, c)); + + + \ No newline at end of file From d4a8f25132304e5be11911bcc52ca6c5c994dcf3 Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sun, 8 Dec 2024 00:41:22 +0800 Subject: [PATCH 16/34] =?UTF-8?q?feature=20#IAY66T=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java | 1 - .../com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java | 2 -- .../liteflow/test/ruleCache/RuleCacheSpringbootTest.java | 1 - .../yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java | 1 - 4 files changed, 5 deletions(-) diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java index 32524ac58..c359683ce 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java @@ -157,7 +157,6 @@ public class RuleCacheTest extends BaseTest { Assertions.assertEquals("a==>b", response.getExecuteStepStr()); } - // 加载缓存, chain1~chain5 private void loadCache() { // 容量上限为5 diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java index 1defd6013..9d688e08d 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java @@ -20,7 +20,6 @@ import org.junit.jupiter.api.Test; import org.noear.solon.annotation.Import; import org.noear.solon.annotation.Inject; import org.noear.solon.test.SolonTest; -import org.springframework.test.context.TestPropertySource; import java.util.HashSet; import java.util.List; @@ -152,7 +151,6 @@ public class RuleCacheSolonTest extends BaseTest { Assertions.assertEquals("a==>b", response.getExecuteStepStr()); } - // 加载缓存, chain1~chain5 private void loadCache() { // 容量上限为5 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 69ea52ebc..1c04cd6e4 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 @@ -154,7 +154,6 @@ public class RuleCacheSpringbootTest extends BaseTest { Assertions.assertEquals("a==>b", response.getExecuteStepStr()); } - // 加载缓存, chain1~chain5 private void loadCache() { // 容量上限为5 diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java index 41ca4d553..916e095d5 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java @@ -151,7 +151,6 @@ public class RuleCacheSpringTest extends BaseTest { Assertions.assertEquals("a==>b", response.getExecuteStepStr()); } - // 加载缓存, chain1~chain5 private void loadCache() { // 容量上限为5 From b14234603aa705d3ceab7a88efd990647c5c914f Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sun, 8 Dec 2024 11:28:00 +0800 Subject: [PATCH 17/34] =?UTF-8?q?feature=20#IAY66T=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/yomahub/liteflow/core/FlowExecutor.java | 2 +- .../yomahub/liteflow/property/LiteflowConfig.java | 12 ++++++------ .../solon/config/LiteflowAutoConfiguration.java | 2 +- .../liteflow/solon/config/LiteflowProperty.java | 10 +++++----- .../liteflow/springboot/LiteflowProperty.java | 10 +++++----- .../config/LiteflowPropertyAutoConfiguration.java | 2 +- .../liteflow/test/ruleCache/RuleCacheTest.java | 2 +- .../src/test/resources/ruleCache/application.xml | 2 +- 8 files changed, 21 insertions(+), 21 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index ec1103e8d..653c652d3 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -228,7 +228,7 @@ public class FlowExecutor { } // 规则缓存 - if (isStart && liteflowConfig.getEnableRuleCache()) { + if (isStart && liteflowConfig.getRuleCacheEnabled()) { initRuleCache(); } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java b/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java index a13367421..6efb50101 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java @@ -114,7 +114,7 @@ public class LiteflowConfig { private Boolean enableNodeInstanceId; // 是否启用规则缓存 - private Boolean enableRuleCache; + private Boolean ruleCacheEnabled; // 规则缓存容量 private Integer ruleCacheCapacity; @@ -488,15 +488,15 @@ public class LiteflowConfig { this.enableNodeInstanceId = enableNodeInstanceId; } - public Boolean getEnableRuleCache() { - if (ObjectUtil.isNull(enableRuleCache)) { + public Boolean getRuleCacheEnabled() { + if (ObjectUtil.isNull(ruleCacheEnabled)) { return Boolean.FALSE; } - return enableRuleCache; + return ruleCacheEnabled; } - public void setEnableRuleCache(Boolean enableRuleCache) { - this.enableRuleCache = enableRuleCache; + public void setRuleCacheEnabled(Boolean ruleCacheEnabled) { + this.ruleCacheEnabled = ruleCacheEnabled; } public Integer getRuleCacheCapacity() { diff --git a/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowAutoConfiguration.java b/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowAutoConfiguration.java index c14d4c11e..932a403c0 100644 --- a/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowAutoConfiguration.java +++ b/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowAutoConfiguration.java @@ -51,7 +51,7 @@ public class LiteflowAutoConfiguration { liteflowConfig.setGlobalThreadPoolQueueSize(property.getGlobalThreadPoolQueueSize()); liteflowConfig.setWhenThreadPoolIsolate(property.getWhenThreadPoolIsolate()); liteflowConfig.setEnableNodeInstanceId(property.isEnableNodeInstanceId()); - liteflowConfig.setEnableRuleCache(property.getRuleCache().getEnabled()); + liteflowConfig.setRuleCacheEnabled(property.getRuleCache().isEnabled()); liteflowConfig.setRuleCacheCapacity(property.getRuleCache().getCapacity()); return liteflowConfig; } diff --git a/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowProperty.java b/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowProperty.java index 1319a8d1a..fc65cac33 100644 --- a/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowProperty.java +++ b/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowProperty.java @@ -102,16 +102,16 @@ public class LiteflowProperty { private boolean enableNodeInstanceId; // 规则缓存配置 - private RuleCache ruleCache; + private RuleCacheProperty ruleCache; - public static class RuleCache { + public static class RuleCacheProperty { // 是否启用规则缓存 private Boolean enabled; // 规则缓存容量 private Integer capacity; - public Boolean getEnabled() { + public Boolean isEnabled() { return enabled; } @@ -369,11 +369,11 @@ public class LiteflowProperty { this.enableNodeInstanceId = enableNodeInstanceId; } - public RuleCache getRuleCache() { + public RuleCacheProperty getRuleCache() { return ruleCache; } - public void setRuleCache(RuleCache ruleCache) { + public void setRuleCache(RuleCacheProperty ruleCache) { this.ruleCache = ruleCache; } } diff --git a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java index bea2a0d4b..6c08c5a4d 100644 --- a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java +++ b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java @@ -102,16 +102,16 @@ public class LiteflowProperty { // 规则缓存配置 @NestedConfigurationProperty - private RuleCache ruleCache; + private RuleCacheProperty ruleCache; - public static class RuleCache { + public static class RuleCacheProperty { // 是否启用规则缓存 private Boolean enabled; // 规则缓存容量 private Integer capacity; - public Boolean getEnabled() { + public Boolean isEnabled() { return enabled; } @@ -360,11 +360,11 @@ public class LiteflowProperty { this.enableNodeInstanceId = enableNodeInstanceId; } - public RuleCache getRuleCache() { + public RuleCacheProperty getRuleCache() { return ruleCache; } - public void setRuleCache(RuleCache ruleCache) { + public void setRuleCache(RuleCacheProperty ruleCache) { this.ruleCache = ruleCache; } } diff --git a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java index 01b9e1afc..71a6756d2 100644 --- a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java +++ b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java @@ -53,7 +53,7 @@ public class LiteflowPropertyAutoConfiguration { liteflowConfig.setGlobalThreadPoolQueueSize(property.getGlobalThreadPoolQueueSize()); liteflowConfig.setGlobalThreadPoolSize(property.getGlobalThreadPoolSize()); liteflowConfig.setEnableNodeInstanceId(property.isEnableNodeInstanceId()); - liteflowConfig.setEnableRuleCache(property.getRuleCache().getEnabled()); + liteflowConfig.setRuleCacheEnabled(property.getRuleCache().isEnabled()); liteflowConfig.setRuleCacheCapacity(property.getRuleCache().getCapacity()); return liteflowConfig; } diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java index c359683ce..44ec5c0d7 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java @@ -39,7 +39,7 @@ public class RuleCacheTest extends BaseTest { public static void init() { LiteflowConfig config = new LiteflowConfig(); config.setRuleSource("ruleCache/flow.el.xml"); - config.setEnableRuleCache(true); + config.setRuleCacheEnabled(true); config.setRuleCacheCapacity(5); flowExecutor = FlowExecutorHolder.loadInstance(config); } diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/ruleCache/application.xml b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/ruleCache/application.xml index 278b241f5..16170f76d 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/ruleCache/application.xml +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/ruleCache/application.xml @@ -15,7 +15,7 @@ - + From 44cedb99d01a55a16fd9b357a403369cfa16dda9 Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Mon, 9 Dec 2024 20:19:27 +0800 Subject: [PATCH 18/34] =?UTF-8?q?feature=20#IAY66T=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=8D=95=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lifecycle/impl/RuleCacheLifeCycle.java | 33 +++++++++++---- .../test/ruleCache/RuleCacheTest.java | 42 ++++++++++++++++++- .../test/ruleCache/RuleCacheSolonTest.java | 42 ++++++++++++++++++- .../ruleCache/RuleCacheSpringbootTest.java | 42 ++++++++++++++++++- .../test/ruleCache/RuleCacheSpringTest.java | 42 ++++++++++++++++++- 5 files changed, 188 insertions(+), 13 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 0c45b4c1a..63166b9b1 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 @@ -12,6 +12,8 @@ import com.yomahub.liteflow.slot.Slot; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import java.util.concurrent.ConcurrentMap; + /** * Chain执行前的缓存处理 * @author DaleLee @@ -40,6 +42,15 @@ public class RuleCacheLifeCycle implements PostProcessFlowExecuteLifeCycle { @Override public void postProcessAfterFlowExecute(String chainId, Slot slot) { + // chain执行时,有可能在未编译前就被淘汰 + // 结果使被淘汰的chain仍持有condition(淘汰后就立刻编译) + // 这里做兜底操作,执行完后再次判断其是否在缓存中 + // 若不在则清空chain的condition + ConcurrentMap<@NonNull String, @NonNull Object> concurrentMap = cache.asMap(); + concurrentMap.computeIfAbsent(chainId, key -> { + cleanChain(chainId); + return null; + }); } @@ -53,15 +64,19 @@ public class RuleCacheLifeCycle implements PostProcessFlowExecuteLifeCycle { private static class ChainRemovalListener implements RemovalListener { @Override - public void onRemoval(@Nullable String chanId, @Nullable Object object, @NonNull RemovalCause removalCause) { - Chain chain = FlowBus.getChain(chanId); - // chain可能已经在FlowBus中被移除了 - if (ObjectUtil.isNull(chain)) { - return; - } - // 清空condition并将chain设置为未编译 - chain.setConditionList(null); - chain.setCompiled(false); + public void onRemoval(@Nullable String chainId, @Nullable Object object, @NonNull RemovalCause removalCause) { + cleanChain(chainId); } } + + private static void cleanChain(String chainId) { + Chain chain = FlowBus.getChain(chainId); + // chain可能已经在FlowBus中被移除了 + if (ObjectUtil.isNull(chain)) { + return; + } + // 清空condition并将chain设置为未编译 + chain.setConditionList(null); + chain.setCompiled(false); + } } diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java index 44ec5c0d7..02d3b6244 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java @@ -25,6 +25,8 @@ import java.util.HashSet; import java.util.List; import java.util.Random; import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; /** * 非Spring环境下的规则缓存测试 @@ -91,7 +93,7 @@ public class RuleCacheTest extends BaseTest { Assertions.assertNull(conditionList); } } - Assertions.assertEquals(5, count); + Assertions.assertTrue(count <= 5); } // 测试开启规则缓存后,进入缓存的chain可以正常被更新 @@ -157,6 +159,44 @@ public class RuleCacheTest extends BaseTest { Assertions.assertEquals("a==>b", response.getExecuteStepStr()); } + // 测试开启规则缓存后,并发执行chain + @Test + public void test6() { + loadCache(); + Random random = new Random(); + List> futureList = CollUtil.newArrayList(); + for (int i = 0; i < 100; i++) { + int id = random.nextInt(10) + 1; + Future future = flowExecutor.execute2Future("chain" + id, "arg"); + futureList.add(future); + } + futureList.forEach(future -> { + try { + LiteflowResponse response = future.get(); + Assertions.assertTrue(response.isSuccess()); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + }); + + // 等待缓存淘汰 + getCache().cleanUp(); + // 测试只有5个chain被编译 + Assertions.assertEquals(10, FlowBus.getChainMap().size()); + + int count = 0; + for (Chain chain : FlowBus.getChainMap().values()) { + List conditionList = chain.getConditionList(); + if (chain.isCompiled()) { + Assertions.assertTrue(CollUtil.isNotEmpty(conditionList)); + count++; + } else { + Assertions.assertNull(conditionList); + } + } + Assertions.assertTrue(count <= 5); + } + // 加载缓存, chain1~chain5 private void loadCache() { // 容量上限为5 diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java index 9d688e08d..bda66ecb5 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java @@ -25,6 +25,8 @@ import java.util.HashSet; import java.util.List; import java.util.Random; import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; /** * Solon环境下规则缓存测试 @@ -85,7 +87,7 @@ public class RuleCacheSolonTest extends BaseTest { Assertions.assertNull(conditionList); } } - Assertions.assertEquals(5, count); + Assertions.assertTrue(count <= 5); } // 测试开启规则缓存后,进入缓存的chain可以正常被更新 @@ -151,6 +153,44 @@ public class RuleCacheSolonTest extends BaseTest { Assertions.assertEquals("a==>b", response.getExecuteStepStr()); } + // 测试开启规则缓存后,并发执行chain + @Test + public void test6() { + loadCache(); + Random random = new Random(); + List> futureList = CollUtil.newArrayList(); + for (int i = 0; i < 100; i++) { + int id = random.nextInt(10) + 1; + Future future = flowExecutor.execute2Future("chain" + id, "arg"); + futureList.add(future); + } + futureList.forEach(future -> { + try { + LiteflowResponse response = future.get(); + Assertions.assertTrue(response.isSuccess()); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + }); + + // 等待缓存淘汰 + getCache().cleanUp(); + // 测试只有5个chain被编译 + Assertions.assertEquals(10, FlowBus.getChainMap().size()); + + int count = 0; + for (Chain chain : FlowBus.getChainMap().values()) { + List conditionList = chain.getConditionList(); + if (chain.isCompiled()) { + Assertions.assertTrue(CollUtil.isNotEmpty(conditionList)); + count++; + } else { + Assertions.assertNull(conditionList); + } + } + Assertions.assertTrue(count <= 5); + } + // 加载缓存, chain1~chain5 private void loadCache() { // 容量上限为5 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 1c04cd6e4..d480bce43 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 @@ -27,6 +27,8 @@ import java.util.HashSet; import java.util.List; import java.util.Random; import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; /** * Springboot环境下规则缓存测试 @@ -88,7 +90,7 @@ public class RuleCacheSpringbootTest extends BaseTest { Assertions.assertNull(conditionList); } } - Assertions.assertEquals(5, count); + Assertions.assertTrue(count <= 5); } // 测试开启规则缓存后,进入缓存的chain可以正常被更新 @@ -154,6 +156,44 @@ public class RuleCacheSpringbootTest extends BaseTest { Assertions.assertEquals("a==>b", response.getExecuteStepStr()); } + // 测试开启规则缓存后,并发执行chain + @Test + public void test6() { + loadCache(); + Random random = new Random(); + List> futureList = CollUtil.newArrayList(); + for (int i = 0; i < 100; i++) { + int id = random.nextInt(10) + 1; + Future future = flowExecutor.execute2Future("chain" + id, "arg"); + futureList.add(future); + } + futureList.forEach(future -> { + try { + LiteflowResponse response = future.get(); + Assertions.assertTrue(response.isSuccess()); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + }); + + // 等待缓存淘汰 + getCache().cleanUp(); + // 测试只有5个chain被编译 + Assertions.assertEquals(10, FlowBus.getChainMap().size()); + + int count = 0; + for (Chain chain : FlowBus.getChainMap().values()) { + List conditionList = chain.getConditionList(); + if (chain.isCompiled()) { + Assertions.assertTrue(CollUtil.isNotEmpty(conditionList)); + count++; + } else { + Assertions.assertNull(conditionList); + } + } + Assertions.assertTrue(count <= 5); + } + // 加载缓存, chain1~chain5 private void loadCache() { // 容量上限为5 diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java index 916e095d5..5f8bcd624 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java @@ -26,6 +26,8 @@ import java.util.HashSet; import java.util.List; import java.util.Random; import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; /** * Spring环境下规则缓存测试 @@ -85,7 +87,7 @@ public class RuleCacheSpringTest extends BaseTest { Assertions.assertNull(conditionList); } } - Assertions.assertEquals(5, count); + Assertions.assertTrue(count <= 5); } // 测试开启规则缓存后,进入缓存的chain可以正常被更新 @@ -151,6 +153,44 @@ public class RuleCacheSpringTest extends BaseTest { Assertions.assertEquals("a==>b", response.getExecuteStepStr()); } + // 测试开启规则缓存后,并发执行chain + @Test + public void test6() { + loadCache(); + Random random = new Random(); + List> futureList = CollUtil.newArrayList(); + for (int i = 0; i < 100; i++) { + int id = random.nextInt(10) + 1; + Future future = flowExecutor.execute2Future("chain" + id, "arg"); + futureList.add(future); + } + futureList.forEach(future -> { + try { + LiteflowResponse response = future.get(); + Assertions.assertTrue(response.isSuccess()); + } catch (InterruptedException | ExecutionException e) { + throw new RuntimeException(e); + } + }); + + // 等待缓存淘汰 + getCache().cleanUp(); + // 测试只有5个chain被编译 + Assertions.assertEquals(10, FlowBus.getChainMap().size()); + + int count = 0; + for (Chain chain : FlowBus.getChainMap().values()) { + List conditionList = chain.getConditionList(); + if (chain.isCompiled()) { + Assertions.assertTrue(CollUtil.isNotEmpty(conditionList)); + count++; + } else { + Assertions.assertNull(conditionList); + } + } + Assertions.assertTrue(count <= 5); + } + // 加载缓存, chain1~chain5 private void loadCache() { // 容量上限为5 From c3c64ce6e45f7eb6bbea4b6fd826f893487f0ad0 Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sun, 9 Feb 2025 15:13:28 +0800 Subject: [PATCH 19/34] =?UTF-8?q?feature=20#IAY66T=20=E4=BF=AE=E5=A4=8DLif?= =?UTF-8?q?eCycle=E9=87=8D=E5=A4=8D=E8=BD=BD=E5=85=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/core/FlowExecutor.java | 11 +++++-- .../yomahub/liteflow/flow/element/Chain.java | 3 +- .../lifecycle/impl/RuleCacheLifeCycle.java | 31 ++++++++++--------- .../ruleCache/RuleCacheSpringbootTest.java | 20 +++++++++--- .../test/ruleCache/RuleCacheSpringTest.java | 28 ++++++++++++++--- 5 files changed, 66 insertions(+), 27 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index 0db1f9a61..34e484cda 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -20,6 +20,7 @@ import com.yomahub.liteflow.enums.ParseModeEnum; import com.yomahub.liteflow.exception.*; import com.yomahub.liteflow.flow.FlowBus; import com.yomahub.liteflow.flow.LiteflowResponse; +import com.yomahub.liteflow.lifecycle.PostProcessChainExecuteLifeCycle; import com.yomahub.liteflow.lifecycle.impl.RuleCacheLifeCycle; import com.yomahub.liteflow.flow.element.Chain; import com.yomahub.liteflow.flow.element.Node; @@ -656,8 +657,14 @@ public class FlowExecutor { LOG.warn("The rule cache capacity {} is too small, it is recommended to be greater than 30% of the number of chains", capacity); } - RuleCacheLifeCycle ruleCacheLifeCycle = new RuleCacheLifeCycle(capacity); - LifeCycleHolder.addLifeCycle(ruleCacheLifeCycle); + // 添加规则缓存生命周期 + List lifeCycleList = LifeCycleHolder.getPostProcessChainExecuteLifeCycleList(); + boolean exist = lifeCycleList.stream() + .anyMatch(lifeCycle -> lifeCycle instanceof RuleCacheLifeCycle); + if (!exist) { + RuleCacheLifeCycle ruleCacheLifeCycle = new RuleCacheLifeCycle(capacity); + LifeCycleHolder.addLifeCycle(ruleCacheLifeCycle); + } // 执行时才解析chain liteflowConfig.setParseMode(ParseModeEnum.PARSE_ONE_ON_FIRST_EXEC); } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java index daab97fd8..becf20330 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java @@ -263,7 +263,8 @@ public class Chain implements Executable{ } // 打印警告,可用于排查临时chain与已有chain重名(几乎不可能发生)而将已有chain覆盖的情况 - LOG.warn("The conditionList of chain[{}] is empty, temporarily using chain[{}] (now removed) to build it.", chainId, tempChainId); + LOG.warn("The conditionList of chain[{}] is empty, " + + "temporarily using chain[{}] (now removed) to build it.", chainId, tempChainId); return tempConditionList; } } 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 63166b9b1..3a4dcf6bf 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 @@ -7,19 +7,17 @@ import com.github.benmanes.caffeine.cache.RemovalCause; import com.github.benmanes.caffeine.cache.RemovalListener; import com.yomahub.liteflow.flow.FlowBus; import com.yomahub.liteflow.flow.element.Chain; -import com.yomahub.liteflow.lifecycle.PostProcessFlowExecuteLifeCycle; +import com.yomahub.liteflow.lifecycle.PostProcessChainExecuteLifeCycle; import com.yomahub.liteflow.slot.Slot; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; -import java.util.concurrent.ConcurrentMap; - /** - * Chain执行前的缓存处理 + * Chain 缓存处理 * @author DaleLee * @since 2.13.0 */ -public class RuleCacheLifeCycle implements PostProcessFlowExecuteLifeCycle { +public class RuleCacheLifeCycle implements PostProcessChainExecuteLifeCycle { // 缓存 private final Cache cache; // 在缓存中与key关联的虚拟值 @@ -33,7 +31,7 @@ public class RuleCacheLifeCycle implements PostProcessFlowExecuteLifeCycle { } @Override - public void postProcessBeforeFlowExecute(String chainId, Slot slot) { + public void postProcessBeforeChainExecute(String chainId, Slot slot) { // 记录chainId在缓存中 // 这里不记录实际的chain是因为chainId对应的chain之后有可能在FlowBus中被移除 // 或被更新替换,以FlowBus中实际存在的chain为准 @@ -41,19 +39,21 @@ public class RuleCacheLifeCycle implements PostProcessFlowExecuteLifeCycle { } @Override - public void postProcessAfterFlowExecute(String chainId, Slot slot) { + public void postProcessAfterChainExecute(String chainId, Slot slot) { // chain执行时,有可能在未编译前就被淘汰 // 结果使被淘汰的chain仍持有condition(淘汰后就立刻编译) // 这里做兜底操作,执行完后再次判断其是否在缓存中 // 若不在则清空chain的condition - ConcurrentMap<@NonNull String, @NonNull Object> concurrentMap = cache.asMap(); - concurrentMap.computeIfAbsent(chainId, key -> { - cleanChain(chainId); - return null; - }); +// ConcurrentMap<@NonNull String, @NonNull Object> concurrentMap = cache.asMap(); +// concurrentMap.computeIfAbsent(chainId, key -> { +// cleanChain(key); +// return null; +// }); + } + public Cache getCache() { return cache; } @@ -75,8 +75,11 @@ public class RuleCacheLifeCycle implements PostProcessFlowExecuteLifeCycle { if (ObjectUtil.isNull(chain)) { return; } - // 清空condition并将chain设置为未编译 - chain.setConditionList(null); +// if (CollUtil.isEmpty(chain.getConditionList())) { +// return; +// } + // 将chain设置为未编译并清空condition chain.setCompiled(false); + chain.setConditionList(null); } } 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 d480bce43..84dea31f7 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 @@ -10,6 +10,7 @@ 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.PostProcessChainExecuteLifeCycle; import com.yomahub.liteflow.lifecycle.PostProcessFlowExecuteLifeCycle; import com.yomahub.liteflow.lifecycle.impl.RuleCacheLifeCycle; import com.yomahub.liteflow.test.BaseTest; @@ -90,7 +91,8 @@ public class RuleCacheSpringbootTest extends BaseTest { Assertions.assertNull(conditionList); } } - Assertions.assertTrue(count <= 5); + //Assertions.assertTrue(count <= 5); + Assertions.assertEquals(count, 5); } // 测试开启规则缓存后,进入缓存的chain可以正常被更新 @@ -191,7 +193,15 @@ public class RuleCacheSpringbootTest extends BaseTest { Assertions.assertNull(conditionList); } } - Assertions.assertTrue(count <= 5); + //Assertions.assertTrue(count <= 5); + Assertions.assertEquals(5, count); + } + + @Test + public void test7() { + for (int i = 0; i < 1000; i++) { + test6(); + } } // 加载缓存, chain1~chain5 @@ -223,9 +233,9 @@ public class RuleCacheSpringbootTest extends BaseTest { } public Cache getCache() { - List lifeCycleList - = LifeCycleHolder.getPostProcessFlowExecuteLifeCycleList(); - for (PostProcessFlowExecuteLifeCycle lifeCycle : lifeCycleList) { + List lifeCycleList + = LifeCycleHolder.getPostProcessChainExecuteLifeCycleList(); + for (PostProcessChainExecuteLifeCycle lifeCycle : lifeCycleList) { if (lifeCycle.getClass().equals(RuleCacheLifeCycle.class)) { RuleCacheLifeCycle ruleCacheLifeCycle = (RuleCacheLifeCycle) lifeCycle; return ruleCacheLifeCycle.getCache(); diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java index 5f8bcd624..0cc32c8ff 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java @@ -10,6 +10,7 @@ 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.PostProcessChainExecuteLifeCycle; import com.yomahub.liteflow.lifecycle.PostProcessFlowExecuteLifeCycle; import com.yomahub.liteflow.lifecycle.impl.RuleCacheLifeCycle; import com.yomahub.liteflow.test.BaseTest; @@ -185,10 +186,26 @@ public class RuleCacheSpringTest extends BaseTest { Assertions.assertTrue(CollUtil.isNotEmpty(conditionList)); count++; } else { - Assertions.assertNull(conditionList); + Assertions.assertTrue(CollUtil.isEmpty(conditionList)); } } - Assertions.assertTrue(count <= 5); + //Assertions.assertTrue(count <= 5); + //System.out.println(getCache().asMap().size()); + Assertions.assertEquals(5, count); + } + + @Test + public void test7() { + for (int i = 0; i < 1000; i++) { + test6(); + } + } + + @Test + public void test8() { + for (int i = 0; i < 1000; i++) { + testRuleCache2(); + } } // 加载缓存, chain1~chain5 @@ -199,6 +216,7 @@ public class RuleCacheSpringTest extends BaseTest { } } + private void loadCache(int count) { // 随机执行chain Random random = new Random(); @@ -220,9 +238,9 @@ public class RuleCacheSpringTest extends BaseTest { } public Cache getCache() { - List lifeCycleList - = LifeCycleHolder.getPostProcessFlowExecuteLifeCycleList(); - for (PostProcessFlowExecuteLifeCycle lifeCycle : lifeCycleList) { + List lifeCycleList + = LifeCycleHolder.getPostProcessChainExecuteLifeCycleList(); + for (PostProcessChainExecuteLifeCycle lifeCycle : lifeCycleList) { if (lifeCycle.getClass().equals(RuleCacheLifeCycle.class)) { RuleCacheLifeCycle ruleCacheLifeCycle = (RuleCacheLifeCycle) lifeCycle; return ruleCacheLifeCycle.getCache(); From 316a539699c8d1ecd2e7c21f6077a8666f702be7 Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sun, 16 Feb 2025 18:14:40 +0800 Subject: [PATCH 20/34] =?UTF-8?q?feature=20#IAY66T=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=B9=B6=E5=8F=91=E4=B8=8Bchain=E6=B8=85=E7=90=86=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/flow/element/Chain.java | 10 +- .../lifecycle/impl/RuleCacheLifeCycle.java | 141 +++++++++++---- .../test/ruleCache/RuleCacheTest.java | 166 +++++++++--------- .../test/ruleCache/RuleCacheSolonTest.java | 164 +++++++++-------- .../ruleCache/RuleCacheSpringbootTest.java | 164 ++++++++--------- .../test/ruleCache/RuleCacheSpringTest.java | 166 ++++++++---------- 6 files changed, 419 insertions(+), 392 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java index becf20330..d99f93234 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java @@ -254,10 +254,16 @@ public class Chain implements Executable{ tempChain.setEl(el); tempChain.setCompiled(false); LiteFlowChainELBuilder.buildUnCompileChain(tempChain); - // 移除临时chain - FlowBus.removeChain(tempChainId); List tempConditionList = tempChain.getConditionList(); + this.conditionList = tempChain.getConditionList(); + this.isCompiled = true; + // 移除临时chain + FlowBus.removeChain(tempChainId); +// if (true) { +// throw new RuntimeException("test..."); +// } + if (CollUtil.isEmpty(tempConditionList)) { throw new FlowSystemException("no conditionList in this chain[" + chainId + "]"); } 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 3a4dcf6bf..d243ca922 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 @@ -1,27 +1,31 @@ package com.yomahub.liteflow.lifecycle.impl; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.RemovalCause; import com.github.benmanes.caffeine.cache.RemovalListener; -import com.yomahub.liteflow.flow.FlowBus; import com.yomahub.liteflow.flow.element.Chain; +import com.yomahub.liteflow.flow.element.Condition; import com.yomahub.liteflow.lifecycle.PostProcessChainExecuteLifeCycle; +import com.yomahub.liteflow.meta.LiteflowMetaOperator; import com.yomahub.liteflow.slot.Slot; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; +import java.util.List; + /** * Chain 缓存处理 * @author DaleLee * @since 2.13.0 */ public class RuleCacheLifeCycle implements PostProcessChainExecuteLifeCycle { - // 缓存 - private final Cache cache; - // 在缓存中与key关联的虚拟值 - private static final Object PRESENT = new Object(); + /** + * 缓存 + */ + private final Cache cache; public RuleCacheLifeCycle(int capacity) { this.cache = Caffeine.newBuilder() @@ -32,52 +36,113 @@ public class RuleCacheLifeCycle implements PostProcessChainExecuteLifeCycle { @Override public void postProcessBeforeChainExecute(String chainId, Slot slot) { - // 记录chainId在缓存中 - // 这里不记录实际的chain是因为chainId对应的chain之后有可能在FlowBus中被移除 - // 或被更新替换,以FlowBus中实际存在的chain为准 - cache.get(chainId, key -> PRESENT); + // 记录 chainId 在缓存中 + // 初始状态为 ACTIVE + cache.get(chainId, key -> new ChainState(State.ACTIVE)); } @Override public void postProcessAfterChainExecute(String chainId, Slot slot) { - // chain执行时,有可能在未编译前就被淘汰 - // 结果使被淘汰的chain仍持有condition(淘汰后就立刻编译) - // 这里做兜底操作,执行完后再次判断其是否在缓存中 - // 若不在则清空chain的condition -// ConcurrentMap<@NonNull String, @NonNull Object> concurrentMap = cache.asMap(); -// concurrentMap.computeIfAbsent(chainId, key -> { -// cleanChain(key); -// return null; -// }); - - - } - - - public Cache getCache() { - return cache; - } - - /** - * 监听在缓存中被移除的chain - */ - private static class ChainRemovalListener implements RemovalListener { - - @Override - public void onRemoval(@Nullable String chainId, @Nullable Object object, @NonNull RemovalCause removalCause) { + // 不在缓存中、或出于非活跃状态,但未被清理 + if (!isActive(chainId) && !isCleaned(chainId)) { cleanChain(chainId); } } + /** + * Chain 状态枚举 + */ + public enum State { + /** + * 活跃状态 + */ + ACTIVE, + /** + * 非活跃状态 (处于淘汰流程中) + */ + INACTIVE + } + + /** + * Chain 在缓存中状态 + */ + public static class ChainState { + /** + * Chain 状态 + */ + private State state; + + public ChainState(State state) { + this.state = state; + } + + public State getState() { + return state; + } + + public void setState(State state) { + this.state = state; + } + } + + + /** + * 监听在缓存中被移除的 Chain + */ + private static class ChainRemovalListener implements RemovalListener { + + @Override + public void onRemoval(@Nullable String chainId, @Nullable ChainState chainState, @NonNull RemovalCause removalCause) { + if (ObjectUtil.isNotNull(chainState)) { + chainState.setState(State.INACTIVE); + } + cleanChain(chainId); + } + } + + /** + * 获取缓存 + * @return cache + */ + public Cache getCache() { + return cache; + } + + /** + * 判断 Chain 的 Condition 是否被清理 + * @param chainId chainId + * @return 被清理返回 true,否则返回 false + */ + private boolean isCleaned(String chainId) { + Chain chain = LiteflowMetaOperator.getChain(chainId); + if (ObjectUtil.isNull(chain)) { + return true; + } + List conditionList = chain.getConditionList(); + return CollUtil.isEmpty(conditionList); + } + + /** + * 判断 Chain 在缓存中是活跃状态 + * @param chainId chainId + * @return 活跃状态返回 true,不在缓存中或处于非活状态返回 false + */ + private boolean isActive(String chainId) { + ChainState chainState = cache.getIfPresent(chainId); + return ObjectUtil.isNotNull(chainState) + && State.ACTIVE.equals(chainState.getState()); + } + + /** + * 清理 Chain 的 Condition + * @param chainId chainId + */ private static void cleanChain(String chainId) { - Chain chain = FlowBus.getChain(chainId); + Chain chain = LiteflowMetaOperator.getChain(chainId); // chain可能已经在FlowBus中被移除了 if (ObjectUtil.isNull(chain)) { return; } -// if (CollUtil.isEmpty(chain.getConditionList())) { -// return; -// } // 将chain设置为未编译并清空condition chain.setCompiled(false); chain.setConditionList(null); diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java index 02d3b6244..abab400a1 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java @@ -11,7 +11,7 @@ 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.PostProcessChainExecuteLifeCycle; import com.yomahub.liteflow.lifecycle.impl.RuleCacheLifeCycle; import com.yomahub.liteflow.property.LiteflowConfig; import com.yomahub.liteflow.test.BaseTest; @@ -21,6 +21,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import javax.annotation.Resource; import java.util.HashSet; import java.util.List; import java.util.Random; @@ -50,7 +51,7 @@ public class RuleCacheTest extends BaseTest { public void reload() { flowExecutor.reloadRule(); // 清空缓存 - Cache cache = getCache(); + Cache cache = getCache(); cache.invalidateAll(); cache.cleanUp(); } @@ -73,15 +74,20 @@ public class RuleCacheTest extends BaseTest { Assertions.assertTrue(response.isSuccess()); } - // 测试缓存数量 + // 测试缓存数量上限(串行) @Test public void testRuleCache2() { // 确保至少执行过5个不同的chain loadCache(); // 随机执行chain - loadCache(100); + Random random = new Random(); + for (int i = 0; i < 100; i++) { + int id = random.nextInt(10) + 1; + flowExecutor.execute2Resp("chain" + id); + } // 等待缓存淘汰 getCache().cleanUp(); + Assertions.assertEquals(10, FlowBus.getChainMap().size()); // 测试只有5个chain被编译 int count = 0; for (Chain chain : FlowBus.getChainMap().values()) { @@ -96,72 +102,9 @@ public class RuleCacheTest extends BaseTest { Assertions.assertTrue(count <= 5); } - // 测试开启规则缓存后,进入缓存的chain可以正常被更新 + // 测试缓存数量上限(并行) @Test public void testRuleCache3() { - loadCache(); - // 缓存快照 - HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); - LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); - Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); - // chain7进入缓存 - Assertions.assertTrue(getCache().asMap().containsKey("chain7")); - // 获得被淘汰chain - String chainId = getEvictedChain(strings); - testEvicted(chainId); - // 更新chain7 - LiteFlowChainELBuilder - .createChain() - .setChainId("chain7") - .setEL("THEN(a, b, c)") - .build(); - // 重新执行chain7 - response = flowExecutor.execute2Resp("chain7", "arg"); - Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("a==>b==>c", response.getExecuteStepStr()); - } - - // 测试开启规则缓存后,进入缓存的chain被移除后无法执行 - @Test - public void testRuleCache4() { - loadCache(); - // 缓存快照 - HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); - LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); - Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); - // chain7进入缓存 - Assertions.assertTrue(getCache().asMap().containsKey("chain7")); - // 获得被淘汰chain - String chainId = getEvictedChain(strings); - testEvicted(chainId); - // 手动移除chain7 - FlowBus.removeChain("chain7"); - response = flowExecutor.execute2Resp("chain7", "arg"); - Assertions.assertFalse(response.isSuccess()); - Assertions.assertEquals(ChainNotFoundException.class, response.getCause().getClass()); - } - - // 测试并发下,正在执行的chain被淘汰仍能执行 - @Test - public void testRuleCache5() throws InterruptedException { - // 模拟清空编译好的chain - Thread thread = new Thread(()-> { - Chain chain1 = FlowBus.getChain("chain1"); - chain1.setCompiled(true); - chain1.setConditionList(null); - }); - thread.start(); - thread.join(); - LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); - Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("a==>b", response.getExecuteStepStr()); - } - - // 测试开启规则缓存后,并发执行chain - @Test - public void test6() { loadCache(); Random random = new Random(); List> futureList = CollUtil.newArrayList(); @@ -181,9 +124,8 @@ public class RuleCacheTest extends BaseTest { // 等待缓存淘汰 getCache().cleanUp(); - // 测试只有5个chain被编译 Assertions.assertEquals(10, FlowBus.getChainMap().size()); - + // 测试只有5个chain被编译 int count = 0; for (Chain chain : FlowBus.getChainMap().values()) { List conditionList = chain.getConditionList(); @@ -197,6 +139,70 @@ public class RuleCacheTest extends BaseTest { Assertions.assertTrue(count <= 5); } + // 测试开启规则缓存后,进入缓存的chain可以正常被更新 + @Test + public void testRuleCache4() { + loadCache(); + // 缓存快照 + HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); + LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); + // chain7进入缓存 + Assertions.assertTrue(getCache().asMap().containsKey("chain7")); + // 更新chain7 + LiteFlowChainELBuilder + .createChain() + .setChainId("chain7") + .setEL("THEN(a, b, c)") + .build(); + // 重新执行chain7 + response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("a==>b==>c", response.getExecuteStepStr()); + } + + // 测试开启规则缓存后,进入缓存的chain被移除后无法执行 + @Test + public void testRuleCache5() { + loadCache(); + // 缓存快照 + HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); + LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); + // chain7进入缓存 + Assertions.assertTrue(getCache().asMap().containsKey("chain7")); + // 手动移除chain7 + FlowBus.removeChain("chain7"); + response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertFalse(response.isSuccess()); + Assertions.assertEquals(ChainNotFoundException.class, response.getCause().getClass()); + } + + // 测试并发下,正在执行的chain的condition被清理但仍能执行 + @Test + public void testRuleCache6() throws InterruptedException { + // 模拟清空编译好的chain + Thread thread = new Thread(()-> { + Chain chain1 = FlowBus.getChain("chain1"); + // 绕过初次编译 + chain1.setCompiled(true); + chain1.setConditionList(null); + }); + thread.start(); + thread.join(); + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("a==>b", response.getExecuteStepStr()); + } + // 加载缓存, chain1~chain5 private void loadCache() { // 容量上限为5 @@ -205,15 +211,6 @@ public class RuleCacheTest extends BaseTest { } } - private void loadCache(int count) { - // 随机执行chain - Random random = new Random(); - for (int i = 0; i < count; i++) { - int id = random.nextInt(10) + 1; - flowExecutor.execute2Resp("chain" + id); - } - } - // 测试 chain 被淘汰 private void testEvicted(String chanId) { Chain chain = FlowBus.getChain(chanId); @@ -225,10 +222,10 @@ public class RuleCacheTest extends BaseTest { Assertions.assertNull(chain.getConditionList()); } - public Cache getCache() { - List lifeCycleList - = LifeCycleHolder.getPostProcessFlowExecuteLifeCycleList(); - for (PostProcessFlowExecuteLifeCycle lifeCycle : lifeCycleList) { + public Cache getCache() { + List lifeCycleList + = LifeCycleHolder.getPostProcessChainExecuteLifeCycleList(); + for (PostProcessChainExecuteLifeCycle lifeCycle : lifeCycleList) { if (lifeCycle.getClass().equals(RuleCacheLifeCycle.class)) { RuleCacheLifeCycle ruleCacheLifeCycle = (RuleCacheLifeCycle) lifeCycle; return ruleCacheLifeCycle.getCache(); @@ -240,12 +237,11 @@ public class RuleCacheTest extends BaseTest { // 获得淘汰的chain,传入淘汰前的chain集合 // 确保只有一个被淘汰时使用 String getEvictedChain(Set set) { - Cache cache = getCache(); + Cache cache = getCache(); cache.cleanUp(); Set<@NonNull String> strings = cache.asMap().keySet(); set.removeAll(strings); Assertions.assertEquals(1, set.size()); return set.iterator().next(); } - } diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java index bda66ecb5..7c06cdfa3 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java @@ -10,7 +10,7 @@ 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.PostProcessChainExecuteLifeCycle; import com.yomahub.liteflow.lifecycle.impl.RuleCacheLifeCycle; import com.yomahub.liteflow.test.BaseTest; import org.checkerframework.checker.nullness.qual.NonNull; @@ -44,7 +44,7 @@ public class RuleCacheSolonTest extends BaseTest { public void reload() { flowExecutor.reloadRule(); // 清空缓存 - Cache cache = getCache(); + Cache cache = getCache(); cache.invalidateAll(); cache.cleanUp(); } @@ -67,15 +67,20 @@ public class RuleCacheSolonTest extends BaseTest { Assertions.assertTrue(response.isSuccess()); } - // 测试缓存数量 + // 测试缓存数量上限(串行) @Test public void testRuleCache2() { // 确保至少执行过5个不同的chain loadCache(); // 随机执行chain - loadCache(100); + Random random = new Random(); + for (int i = 0; i < 100; i++) { + int id = random.nextInt(10) + 1; + flowExecutor.execute2Resp("chain" + id); + } // 等待缓存淘汰 getCache().cleanUp(); + Assertions.assertEquals(10, FlowBus.getChainMap().size()); // 测试只有5个chain被编译 int count = 0; for (Chain chain : FlowBus.getChainMap().values()) { @@ -90,72 +95,9 @@ public class RuleCacheSolonTest extends BaseTest { Assertions.assertTrue(count <= 5); } - // 测试开启规则缓存后,进入缓存的chain可以正常被更新 + // 测试缓存数量上限(并行) @Test public void testRuleCache3() { - loadCache(); - // 缓存快照 - HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); - LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); - Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); - // chain7进入缓存 - Assertions.assertTrue(getCache().asMap().containsKey("chain7")); - // 获得被淘汰chain - String chainId = getEvictedChain(strings); - testEvicted(chainId); - // 更新chain7 - LiteFlowChainELBuilder - .createChain() - .setChainId("chain7") - .setEL("THEN(a, b, c)") - .build(); - // 重新执行chain7 - response = flowExecutor.execute2Resp("chain7", "arg"); - Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("a==>b==>c", response.getExecuteStepStr()); - } - - // 测试开启规则缓存后,进入缓存的chain被移除后无法执行 - @Test - public void testRuleCache4() { - loadCache(); - // 缓存快照 - HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); - LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); - Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); - // chain7进入缓存 - Assertions.assertTrue(getCache().asMap().containsKey("chain7")); - // 获得被淘汰chain - String chainId = getEvictedChain(strings); - testEvicted(chainId); - // 手动移除chain7 - FlowBus.removeChain("chain7"); - response = flowExecutor.execute2Resp("chain7", "arg"); - Assertions.assertFalse(response.isSuccess()); - Assertions.assertEquals(ChainNotFoundException.class, response.getCause().getClass()); - } - - // 测试并发下,正在执行的chain被淘汰仍能执行 - @Test - public void testRuleCache5() throws InterruptedException { - // 模拟清空编译好的chain - Thread thread = new Thread(()-> { - Chain chain1 = FlowBus.getChain("chain1"); - chain1.setCompiled(true); - chain1.setConditionList(null); - }); - thread.start(); - thread.join(); - LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); - Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("a==>b", response.getExecuteStepStr()); - } - - // 测试开启规则缓存后,并发执行chain - @Test - public void test6() { loadCache(); Random random = new Random(); List> futureList = CollUtil.newArrayList(); @@ -175,9 +117,8 @@ public class RuleCacheSolonTest extends BaseTest { // 等待缓存淘汰 getCache().cleanUp(); - // 测试只有5个chain被编译 Assertions.assertEquals(10, FlowBus.getChainMap().size()); - + // 测试只有5个chain被编译 int count = 0; for (Chain chain : FlowBus.getChainMap().values()) { List conditionList = chain.getConditionList(); @@ -191,6 +132,70 @@ public class RuleCacheSolonTest extends BaseTest { Assertions.assertTrue(count <= 5); } + // 测试开启规则缓存后,进入缓存的chain可以正常被更新 + @Test + public void testRuleCache4() { + loadCache(); + // 缓存快照 + HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); + LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); + // chain7进入缓存 + Assertions.assertTrue(getCache().asMap().containsKey("chain7")); + // 更新chain7 + LiteFlowChainELBuilder + .createChain() + .setChainId("chain7") + .setEL("THEN(a, b, c)") + .build(); + // 重新执行chain7 + response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("a==>b==>c", response.getExecuteStepStr()); + } + + // 测试开启规则缓存后,进入缓存的chain被移除后无法执行 + @Test + public void testRuleCache5() { + loadCache(); + // 缓存快照 + HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); + LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); + // chain7进入缓存 + Assertions.assertTrue(getCache().asMap().containsKey("chain7")); + // 手动移除chain7 + FlowBus.removeChain("chain7"); + response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertFalse(response.isSuccess()); + Assertions.assertEquals(ChainNotFoundException.class, response.getCause().getClass()); + } + + // 测试并发下,正在执行的chain的condition被清理但仍能执行 + @Test + public void testRuleCache6() throws InterruptedException { + // 模拟清空编译好的chain + Thread thread = new Thread(()-> { + Chain chain1 = FlowBus.getChain("chain1"); + // 绕过初次编译 + chain1.setCompiled(true); + chain1.setConditionList(null); + }); + thread.start(); + thread.join(); + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("a==>b", response.getExecuteStepStr()); + } + // 加载缓存, chain1~chain5 private void loadCache() { // 容量上限为5 @@ -199,15 +204,6 @@ public class RuleCacheSolonTest extends BaseTest { } } - private void loadCache(int count) { - // 随机执行chain - Random random = new Random(); - for (int i = 0; i < count; i++) { - int id = random.nextInt(10) + 1; - flowExecutor.execute2Resp("chain" + id); - } - } - // 测试 chain 被淘汰 private void testEvicted(String chanId) { Chain chain = FlowBus.getChain(chanId); @@ -219,10 +215,10 @@ public class RuleCacheSolonTest extends BaseTest { Assertions.assertNull(chain.getConditionList()); } - public Cache getCache() { - List lifeCycleList - = LifeCycleHolder.getPostProcessFlowExecuteLifeCycleList(); - for (PostProcessFlowExecuteLifeCycle lifeCycle : lifeCycleList) { + public Cache getCache() { + List lifeCycleList + = LifeCycleHolder.getPostProcessChainExecuteLifeCycleList(); + for (PostProcessChainExecuteLifeCycle lifeCycle : lifeCycleList) { if (lifeCycle.getClass().equals(RuleCacheLifeCycle.class)) { RuleCacheLifeCycle ruleCacheLifeCycle = (RuleCacheLifeCycle) lifeCycle; return ruleCacheLifeCycle.getCache(); @@ -234,7 +230,7 @@ public class RuleCacheSolonTest extends BaseTest { // 获得淘汰的chain,传入淘汰前的chain集合 // 确保只有一个被淘汰时使用 String getEvictedChain(Set set) { - Cache cache = getCache(); + Cache cache = getCache(); cache.cleanUp(); Set<@NonNull String> strings = cache.asMap().keySet(); set.removeAll(strings); 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 84dea31f7..024aedbdf 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 @@ -11,7 +11,6 @@ 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.PostProcessChainExecuteLifeCycle; -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; @@ -48,7 +47,7 @@ public class RuleCacheSpringbootTest extends BaseTest { public void reload() { flowExecutor.reloadRule(); // 清空缓存 - Cache cache = getCache(); + Cache cache = getCache(); cache.invalidateAll(); cache.cleanUp(); } @@ -71,15 +70,20 @@ public class RuleCacheSpringbootTest extends BaseTest { Assertions.assertTrue(response.isSuccess()); } - // 测试缓存数量 + // 测试缓存数量上限(串行) @Test public void testRuleCache2() { // 确保至少执行过5个不同的chain loadCache(); // 随机执行chain - loadCache(100); + Random random = new Random(); + for (int i = 0; i < 100; i++) { + int id = random.nextInt(10) + 1; + flowExecutor.execute2Resp("chain" + id); + } // 等待缓存淘汰 getCache().cleanUp(); + Assertions.assertEquals(10, FlowBus.getChainMap().size()); // 测试只有5个chain被编译 int count = 0; for (Chain chain : FlowBus.getChainMap().values()) { @@ -91,76 +95,12 @@ public class RuleCacheSpringbootTest extends BaseTest { Assertions.assertNull(conditionList); } } - //Assertions.assertTrue(count <= 5); - Assertions.assertEquals(count, 5); + Assertions.assertTrue(count <= 5); } - // 测试开启规则缓存后,进入缓存的chain可以正常被更新 + // 测试缓存数量上限(并行) @Test public void testRuleCache3() { - loadCache(); - // 缓存快照 - HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); - LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); - Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); - // chain7进入缓存 - Assertions.assertTrue(getCache().asMap().containsKey("chain7")); - // 获得被淘汰chain - String chainId = getEvictedChain(strings); - testEvicted(chainId); - // 更新chain7 - LiteFlowChainELBuilder - .createChain() - .setChainId("chain7") - .setEL("THEN(a, b, c)") - .build(); - // 重新执行chain7 - response = flowExecutor.execute2Resp("chain7", "arg"); - Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("a==>b==>c", response.getExecuteStepStr()); - } - - // 测试开启规则缓存后,进入缓存的chain被移除后无法执行 - @Test - public void testRuleCache4() { - loadCache(); - // 缓存快照 - HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); - LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); - Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); - // chain7进入缓存 - Assertions.assertTrue(getCache().asMap().containsKey("chain7")); - // 获得被淘汰chain - String chainId = getEvictedChain(strings); - testEvicted(chainId); - // 手动移除chain7 - FlowBus.removeChain("chain7"); - response = flowExecutor.execute2Resp("chain7", "arg"); - Assertions.assertFalse(response.isSuccess()); - Assertions.assertEquals(ChainNotFoundException.class, response.getCause().getClass()); - } - - // 测试并发下,正在执行的chain被淘汰仍能执行 - @Test - public void testRuleCache5() throws InterruptedException { - // 模拟清空编译好的chain - Thread thread = new Thread(()-> { - Chain chain1 = FlowBus.getChain("chain1"); - chain1.setCompiled(true); - chain1.setConditionList(null); - }); - thread.start(); - thread.join(); - LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); - Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("a==>b", response.getExecuteStepStr()); - } - - // 测试开启规则缓存后,并发执行chain - @Test - public void test6() { loadCache(); Random random = new Random(); List> futureList = CollUtil.newArrayList(); @@ -180,9 +120,8 @@ public class RuleCacheSpringbootTest extends BaseTest { // 等待缓存淘汰 getCache().cleanUp(); - // 测试只有5个chain被编译 Assertions.assertEquals(10, FlowBus.getChainMap().size()); - + // 测试只有5个chain被编译 int count = 0; for (Chain chain : FlowBus.getChainMap().values()) { List conditionList = chain.getConditionList(); @@ -193,15 +132,71 @@ public class RuleCacheSpringbootTest extends BaseTest { Assertions.assertNull(conditionList); } } - //Assertions.assertTrue(count <= 5); - Assertions.assertEquals(5, count); + Assertions.assertTrue(count <= 5); } + // 测试开启规则缓存后,进入缓存的chain可以正常被更新 @Test - public void test7() { - for (int i = 0; i < 1000; i++) { - test6(); - } + public void testRuleCache4() { + loadCache(); + // 缓存快照 + HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); + LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); + // chain7进入缓存 + Assertions.assertTrue(getCache().asMap().containsKey("chain7")); + // 更新chain7 + LiteFlowChainELBuilder + .createChain() + .setChainId("chain7") + .setEL("THEN(a, b, c)") + .build(); + // 重新执行chain7 + response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("a==>b==>c", response.getExecuteStepStr()); + } + + // 测试开启规则缓存后,进入缓存的chain被移除后无法执行 + @Test + public void testRuleCache5() { + loadCache(); + // 缓存快照 + HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); + LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); + // chain7进入缓存 + Assertions.assertTrue(getCache().asMap().containsKey("chain7")); + // 手动移除chain7 + FlowBus.removeChain("chain7"); + response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertFalse(response.isSuccess()); + Assertions.assertEquals(ChainNotFoundException.class, response.getCause().getClass()); + } + + // 测试并发下,正在执行的chain的condition被清理但仍能执行 + @Test + public void testRuleCache6() throws InterruptedException { + // 模拟清空编译好的chain + Thread thread = new Thread(()-> { + Chain chain1 = FlowBus.getChain("chain1"); + // 绕过初次编译 + chain1.setCompiled(true); + chain1.setConditionList(null); + }); + thread.start(); + thread.join(); + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("a==>b", response.getExecuteStepStr()); } // 加载缓存, chain1~chain5 @@ -212,15 +207,6 @@ public class RuleCacheSpringbootTest extends BaseTest { } } - private void loadCache(int count) { - // 随机执行chain - Random random = new Random(); - for (int i = 0; i < count; i++) { - int id = random.nextInt(10) + 1; - flowExecutor.execute2Resp("chain" + id); - } - } - // 测试 chain 被淘汰 private void testEvicted(String chanId) { Chain chain = FlowBus.getChain(chanId); @@ -232,7 +218,7 @@ public class RuleCacheSpringbootTest extends BaseTest { Assertions.assertNull(chain.getConditionList()); } - public Cache getCache() { + public Cache getCache() { List lifeCycleList = LifeCycleHolder.getPostProcessChainExecuteLifeCycleList(); for (PostProcessChainExecuteLifeCycle lifeCycle : lifeCycleList) { @@ -247,7 +233,7 @@ public class RuleCacheSpringbootTest extends BaseTest { // 获得淘汰的chain,传入淘汰前的chain集合 // 确保只有一个被淘汰时使用 String getEvictedChain(Set set) { - Cache cache = getCache(); + Cache cache = getCache(); cache.cleanUp(); Set<@NonNull String> strings = cache.asMap().keySet(); set.removeAll(strings); diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java index 0cc32c8ff..ec530cbd7 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java @@ -11,7 +11,6 @@ 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.PostProcessChainExecuteLifeCycle; -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; @@ -45,7 +44,7 @@ public class RuleCacheSpringTest extends BaseTest { public void reload() { flowExecutor.reloadRule(); // 清空缓存 - Cache cache = getCache(); + Cache cache = getCache(); cache.invalidateAll(); cache.cleanUp(); } @@ -68,15 +67,20 @@ public class RuleCacheSpringTest extends BaseTest { Assertions.assertTrue(response.isSuccess()); } - // 测试缓存数量 + // 测试缓存数量上限(串行) @Test public void testRuleCache2() { // 确保至少执行过5个不同的chain loadCache(); // 随机执行chain - loadCache(100); + Random random = new Random(); + for (int i = 0; i < 100; i++) { + int id = random.nextInt(10) + 1; + flowExecutor.execute2Resp("chain" + id); + } // 等待缓存淘汰 getCache().cleanUp(); + Assertions.assertEquals(10, FlowBus.getChainMap().size()); // 测试只有5个chain被编译 int count = 0; for (Chain chain : FlowBus.getChainMap().values()) { @@ -91,72 +95,9 @@ public class RuleCacheSpringTest extends BaseTest { Assertions.assertTrue(count <= 5); } - // 测试开启规则缓存后,进入缓存的chain可以正常被更新 + // 测试缓存数量上限(并行) @Test public void testRuleCache3() { - loadCache(); - // 缓存快照 - HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); - LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); - Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); - // chain7进入缓存 - Assertions.assertTrue(getCache().asMap().containsKey("chain7")); - // 获得被淘汰chain - String chainId = getEvictedChain(strings); - testEvicted(chainId); - // 更新chain7 - LiteFlowChainELBuilder - .createChain() - .setChainId("chain7") - .setEL("THEN(a, b, c)") - .build(); - // 重新执行chain7 - response = flowExecutor.execute2Resp("chain7", "arg"); - Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("a==>b==>c", response.getExecuteStepStr()); - } - - // 测试开启规则缓存后,进入缓存的chain被移除后无法执行 - @Test - public void testRuleCache4() { - loadCache(); - // 缓存快照 - HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); - LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); - Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); - // chain7进入缓存 - Assertions.assertTrue(getCache().asMap().containsKey("chain7")); - // 获得被淘汰chain - String chainId = getEvictedChain(strings); - testEvicted(chainId); - // 手动移除chain7 - FlowBus.removeChain("chain7"); - response = flowExecutor.execute2Resp("chain7", "arg"); - Assertions.assertFalse(response.isSuccess()); - Assertions.assertEquals(ChainNotFoundException.class, response.getCause().getClass()); - } - - // 测试并发下,正在执行的chain被淘汰仍能执行 - @Test - public void testRuleCache5() throws InterruptedException { - // 模拟清空编译好的chain - Thread thread = new Thread(()-> { - Chain chain1 = FlowBus.getChain("chain1"); - chain1.setCompiled(true); - chain1.setConditionList(null); - }); - thread.start(); - thread.join(); - LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); - Assertions.assertTrue(response.isSuccess()); - Assertions.assertEquals("a==>b", response.getExecuteStepStr()); - } - - // 测试开启规则缓存后,并发执行chain - @Test - public void test6() { loadCache(); Random random = new Random(); List> futureList = CollUtil.newArrayList(); @@ -176,9 +117,8 @@ public class RuleCacheSpringTest extends BaseTest { // 等待缓存淘汰 getCache().cleanUp(); - // 测试只有5个chain被编译 Assertions.assertEquals(10, FlowBus.getChainMap().size()); - + // 测试只有5个chain被编译 int count = 0; for (Chain chain : FlowBus.getChainMap().values()) { List conditionList = chain.getConditionList(); @@ -186,26 +126,74 @@ public class RuleCacheSpringTest extends BaseTest { Assertions.assertTrue(CollUtil.isNotEmpty(conditionList)); count++; } else { - Assertions.assertTrue(CollUtil.isEmpty(conditionList)); + Assertions.assertNull(conditionList); } } - //Assertions.assertTrue(count <= 5); - //System.out.println(getCache().asMap().size()); - Assertions.assertEquals(5, count); + Assertions.assertTrue(count <= 5); } + // 测试开启规则缓存后,进入缓存的chain可以正常被更新 @Test - public void test7() { - for (int i = 0; i < 1000; i++) { - test6(); - } + public void testRuleCache4() { + loadCache(); + // 缓存快照 + HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); + LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); + // chain7进入缓存 + Assertions.assertTrue(getCache().asMap().containsKey("chain7")); + // 更新chain7 + LiteFlowChainELBuilder + .createChain() + .setChainId("chain7") + .setEL("THEN(a, b, c)") + .build(); + // 重新执行chain7 + response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("a==>b==>c", response.getExecuteStepStr()); } + // 测试开启规则缓存后,进入缓存的chain被移除后无法执行 @Test - public void test8() { - for (int i = 0; i < 1000; i++) { - testRuleCache2(); - } + public void testRuleCache5() { + loadCache(); + // 缓存快照 + HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); + LiteflowResponse response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("x==>a==>b", response.getExecuteStepStr()); + // 获得被淘汰chain + String chainId = getEvictedChain(strings); + testEvicted(chainId); + // chain7进入缓存 + Assertions.assertTrue(getCache().asMap().containsKey("chain7")); + // 手动移除chain7 + FlowBus.removeChain("chain7"); + response = flowExecutor.execute2Resp("chain7", "arg"); + Assertions.assertFalse(response.isSuccess()); + Assertions.assertEquals(ChainNotFoundException.class, response.getCause().getClass()); + } + + // 测试并发下,正在执行的chain的condition被清理但仍能执行 + @Test + public void testRuleCache6() throws InterruptedException { + // 模拟清空编译好的chain + Thread thread = new Thread(()-> { + Chain chain1 = FlowBus.getChain("chain1"); + // 绕过初次编译 + chain1.setCompiled(true); + chain1.setConditionList(null); + }); + thread.start(); + thread.join(); + LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); + Assertions.assertTrue(response.isSuccess()); + Assertions.assertEquals("a==>b", response.getExecuteStepStr()); } // 加载缓存, chain1~chain5 @@ -216,16 +204,6 @@ public class RuleCacheSpringTest extends BaseTest { } } - - private void loadCache(int count) { - // 随机执行chain - Random random = new Random(); - for (int i = 0; i < count; i++) { - int id = random.nextInt(10) + 1; - flowExecutor.execute2Resp("chain" + id); - } - } - // 测试 chain 被淘汰 private void testEvicted(String chanId) { Chain chain = FlowBus.getChain(chanId); @@ -237,7 +215,7 @@ public class RuleCacheSpringTest extends BaseTest { Assertions.assertNull(chain.getConditionList()); } - public Cache getCache() { + public Cache getCache() { List lifeCycleList = LifeCycleHolder.getPostProcessChainExecuteLifeCycleList(); for (PostProcessChainExecuteLifeCycle lifeCycle : lifeCycleList) { @@ -252,7 +230,7 @@ public class RuleCacheSpringTest extends BaseTest { // 获得淘汰的chain,传入淘汰前的chain集合 // 确保只有一个被淘汰时使用 String getEvictedChain(Set set) { - Cache cache = getCache(); + Cache cache = getCache(); cache.cleanUp(); Set<@NonNull String> strings = cache.asMap().keySet(); set.removeAll(strings); From 1aed0bcb8737edbd55430d5f06c79a283c968f45 Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sun, 16 Feb 2025 19:31:26 +0800 Subject: [PATCH 21/34] =?UTF-8?q?feature=20#IAY66T=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/yomahub/liteflow/flow/element/Chain.java | 2 +- .../com/yomahub/liteflow/lifecycle/impl/RuleCacheLifeCycle.java | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java index d99f93234..37fa4625c 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java @@ -108,7 +108,7 @@ public class Chain implements Executable{ // 因为在正式执行condition之前,this.conditionList有可能被其他线程置空 // 比如,该chain在规则缓存中被淘汰 List conditionListRef = this.conditionList; - // 但在编译后到拿到引用之前,this.conditionList也有可能被置空 + // 但在编译后到拿到引用之前,this.conditionList可能已经被置空了 if (CollUtil.isEmpty(conditionListRef)) { // 如果conditionListRef为空, // 构建临时conditionList确保本次一定可以执行 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 d243ca922..80d1d99cc 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 @@ -85,7 +85,6 @@ public class RuleCacheLifeCycle implements PostProcessChainExecuteLifeCycle { } } - /** * 监听在缓存中被移除的 Chain */ From ee4dc48aeab48455de885537b8d8389893812f8c Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Mon, 17 Feb 2025 23:54:03 +0800 Subject: [PATCH 22/34] =?UTF-8?q?feature=20#IAY66T=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=8D=95=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/META-INF/liteflow-default.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/liteflow-solon-plugin/src/main/resources/META-INF/liteflow-default.properties b/liteflow-solon-plugin/src/main/resources/META-INF/liteflow-default.properties index ef67b23eb..8bc5b482e 100644 --- a/liteflow-solon-plugin/src/main/resources/META-INF/liteflow-default.properties +++ b/liteflow-solon-plugin/src/main/resources/META-INF/liteflow-default.properties @@ -19,5 +19,4 @@ liteflow.global-thread-pool-size=16 liteflow.global-thread-pool-queue-size=512 liteflow.global-thread-pool-executor-class=com.yomahub.liteflow.thread.LiteFlowDefaultGlobalExecutorBuilder liteflow.enable-node-instance-id=false -liteflow.enable-node-instance-id=true liteflow.rule-cache.enabled=false From 26e8d293f57c7c7f48acda8eaaea4d97afbee731 Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Tue, 25 Feb 2025 23:08:00 +0800 Subject: [PATCH 23/34] =?UTF-8?q?feature=20#IAY66T=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/yomahub/liteflow/lifecycle/impl/RuleCacheLifeCycle.java | 2 +- .../java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java | 1 - .../com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java | 1 - .../liteflow/test/ruleCache/RuleCacheSpringbootTest.java | 1 - .../yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java | 1 - 5 files changed, 1 insertion(+), 5 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 80d1d99cc..c81be6551 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 @@ -19,7 +19,7 @@ import java.util.List; /** * Chain 缓存处理 * @author DaleLee - * @since 2.13.0 + * @since 2.13.1 */ public class RuleCacheLifeCycle implements PostProcessChainExecuteLifeCycle { /** diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java index abab400a1..77a0f9e2d 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java @@ -32,7 +32,6 @@ import java.util.concurrent.Future; /** * 非Spring环境下的规则缓存测试 * @author DaleLee - * @since 2.13.0 */ public class RuleCacheTest extends BaseTest { diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java index 7c06cdfa3..beb281ee0 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java @@ -31,7 +31,6 @@ import java.util.concurrent.Future; /** * Solon环境下规则缓存测试 * @author DaleLee - * @since 2.13.0 */ @SolonTest @Import(profiles="classpath:/ruleCache/application.properties") 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 024aedbdf..3d75814f0 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 @@ -33,7 +33,6 @@ import java.util.concurrent.Future; /** * Springboot环境下规则缓存测试 * @author DaleLee - * @since 2.13.0 */ @TestPropertySource(value = "classpath:/ruleCache/application.properties") @SpringBootTest(classes = RuleCacheSpringbootTest.class) diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java index ec530cbd7..d97d82947 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java @@ -32,7 +32,6 @@ import java.util.concurrent.Future; /** * Spring环境下规则缓存测试 * @author DaleLee - * @since 2.13.0 */ @ExtendWith(SpringExtension.class) @ContextConfiguration("classpath:/ruleCache/application.xml") From ecbea880049b3a156557b090e808356813ad1451 Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Wed, 26 Feb 2025 22:40:09 +0800 Subject: [PATCH 24/34] =?UTF-8?q?feature=20#IAY66T=20=E7=94=9F=E5=91=BD?= =?UTF-8?q?=E5=91=A8=E6=9C=9F=E5=AE=9E=E7=8E=B0=E4=B8=BA=E5=8D=95=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/core/FlowExecutor.java | 4 +-- .../lifecycle/impl/RuleCacheLifeCycle.java | 25 ++++++++++++++++++- .../test/ruleCache/RuleCacheTest.java | 10 +------- .../test/ruleCache/RuleCacheSolonTest.java | 10 +------- .../ruleCache/RuleCacheSpringbootTest.java | 10 +------- .../test/ruleCache/RuleCacheSpringTest.java | 10 +------- 6 files changed, 30 insertions(+), 39 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index 34e484cda..4a4d9031a 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -662,8 +662,8 @@ public class FlowExecutor { boolean exist = lifeCycleList.stream() .anyMatch(lifeCycle -> lifeCycle instanceof RuleCacheLifeCycle); if (!exist) { - RuleCacheLifeCycle ruleCacheLifeCycle = new RuleCacheLifeCycle(capacity); - LifeCycleHolder.addLifeCycle(ruleCacheLifeCycle); + RuleCacheLifeCycle.initIfAbsent(capacity); + LifeCycleHolder.addLifeCycle(RuleCacheLifeCycle.getLifeCycle()); } // 执行时才解析chain liteflowConfig.setParseMode(ParseModeEnum.PARSE_ONE_ON_FIRST_EXEC); 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 c81be6551..67eb86bc3 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 @@ -27,7 +27,12 @@ public class RuleCacheLifeCycle implements PostProcessChainExecuteLifeCycle { */ private final Cache cache; - public RuleCacheLifeCycle(int capacity) { + /** + * 实例 + */ + private static RuleCacheLifeCycle INSTANCE; + + private RuleCacheLifeCycle(int capacity) { this.cache = Caffeine.newBuilder() .maximumSize(capacity) .evictionListener(new ChainRemovalListener()) @@ -146,4 +151,22 @@ public class RuleCacheLifeCycle implements PostProcessChainExecuteLifeCycle { chain.setCompiled(false); chain.setConditionList(null); } + + /** + * 初始化生命周期实例 + * @param capacity 缓存容量 + */ + public synchronized static void initIfAbsent(int capacity) { + if (ObjectUtil.isNull(INSTANCE)) { + INSTANCE = new RuleCacheLifeCycle(capacity); + } + } + + /** + * 获取生命周期实例 + * @return lifeCycle + */ + public static RuleCacheLifeCycle getLifeCycle() { + return INSTANCE; + } } diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java index 77a0f9e2d..1dedac580 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java @@ -222,15 +222,7 @@ public class RuleCacheTest extends BaseTest { } public Cache getCache() { - List lifeCycleList - = LifeCycleHolder.getPostProcessChainExecuteLifeCycleList(); - for (PostProcessChainExecuteLifeCycle lifeCycle : lifeCycleList) { - if (lifeCycle.getClass().equals(RuleCacheLifeCycle.class)) { - RuleCacheLifeCycle ruleCacheLifeCycle = (RuleCacheLifeCycle) lifeCycle; - return ruleCacheLifeCycle.getCache(); - } - } - return null; + return RuleCacheLifeCycle.getLifeCycle().getCache(); } // 获得淘汰的chain,传入淘汰前的chain集合 diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java index beb281ee0..392e70de7 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java @@ -215,15 +215,7 @@ public class RuleCacheSolonTest extends BaseTest { } public Cache getCache() { - List lifeCycleList - = LifeCycleHolder.getPostProcessChainExecuteLifeCycleList(); - for (PostProcessChainExecuteLifeCycle lifeCycle : lifeCycleList) { - if (lifeCycle.getClass().equals(RuleCacheLifeCycle.class)) { - RuleCacheLifeCycle ruleCacheLifeCycle = (RuleCacheLifeCycle) lifeCycle; - return ruleCacheLifeCycle.getCache(); - } - } - return null; + return RuleCacheLifeCycle.getLifeCycle().getCache(); } // 获得淘汰的chain,传入淘汰前的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 3d75814f0..1611bb65d 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 @@ -218,15 +218,7 @@ public class RuleCacheSpringbootTest extends BaseTest { } public Cache getCache() { - List lifeCycleList - = LifeCycleHolder.getPostProcessChainExecuteLifeCycleList(); - for (PostProcessChainExecuteLifeCycle lifeCycle : lifeCycleList) { - if (lifeCycle.getClass().equals(RuleCacheLifeCycle.class)) { - RuleCacheLifeCycle ruleCacheLifeCycle = (RuleCacheLifeCycle) lifeCycle; - return ruleCacheLifeCycle.getCache(); - } - } - return null; + return RuleCacheLifeCycle.getLifeCycle().getCache(); } // 获得淘汰的chain,传入淘汰前的chain集合 diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java index d97d82947..f76a1bc1a 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java @@ -215,15 +215,7 @@ public class RuleCacheSpringTest extends BaseTest { } public Cache getCache() { - List lifeCycleList - = LifeCycleHolder.getPostProcessChainExecuteLifeCycleList(); - for (PostProcessChainExecuteLifeCycle lifeCycle : lifeCycleList) { - if (lifeCycle.getClass().equals(RuleCacheLifeCycle.class)) { - RuleCacheLifeCycle ruleCacheLifeCycle = (RuleCacheLifeCycle) lifeCycle; - return ruleCacheLifeCycle.getCache(); - } - } - return null; + return RuleCacheLifeCycle.getLifeCycle().getCache(); } // 获得淘汰的chain,传入淘汰前的chain集合 From d6a66dafd79823f00b1e6ae3397fb00d9cda2c7e Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sat, 22 Mar 2025 14:47:22 +0800 Subject: [PATCH 25/34] =?UTF-8?q?feature=20#IAY66T=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/core/FlowExecutor.java | 36 +++++++++++++------ .../yomahub/liteflow/flow/element/Chain.java | 3 -- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index 4a4d9031a..9f247c324 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -101,6 +101,12 @@ public class FlowExecutor { IdGeneratorHolder.init(); } + // 规则缓存 + if (isStart && liteflowConfig.getRuleCacheEnabled()) { + // 放到解析节点后,是因为要根据节点数量判断缓存大小设置是否合理 + initRuleCache(); + } + String ruleSource = liteflowConfig.getRuleSource(); if (StrUtil.isBlank(ruleSource)) { // 查看有没有Parser的SPI实现 @@ -228,9 +234,9 @@ public class FlowExecutor { } - // 规则缓存 - if (isStart && liteflowConfig.getRuleCacheEnabled()) { - initRuleCache(); + // 初始化或reload时,评估规则缓存容量大小 + if (liteflowConfig.getRuleCacheEnabled()) { + evaluateRuleCacheCapacity(); } } @@ -650,13 +656,6 @@ public class FlowExecutor { throw new ConfigErrorException("The rule cache capacity must be greater than 0"); } - // 容量不足chain总数的30%给予警告 - int chainNum = FlowBus.getChainMap().size(); - double threshold = chainNum * 0.3; - if (capacity < threshold) { - LOG.warn("The rule cache capacity {} is too small, it is recommended to be greater than 30% of the number of chains", capacity); - } - // 添加规则缓存生命周期 List lifeCycleList = LifeCycleHolder.getPostProcessChainExecuteLifeCycleList(); boolean exist = lifeCycleList.stream() @@ -665,7 +664,22 @@ public class FlowExecutor { RuleCacheLifeCycle.initIfAbsent(capacity); LifeCycleHolder.addLifeCycle(RuleCacheLifeCycle.getLifeCycle()); } + // 执行时才解析chain - liteflowConfig.setParseMode(ParseModeEnum.PARSE_ONE_ON_FIRST_EXEC); + if (!ParseModeEnum.PARSE_ONE_ON_FIRST_EXEC.equals(liteflowConfig.getParseMode())) { + liteflowConfig.setParseMode(ParseModeEnum.PARSE_ONE_ON_FIRST_EXEC); + LOG.warn("The rule cache is enabled, so the parse mode is forcibly set to PARSE_ONE_ON_FIRST_EXE."); + } + } + + // 评估规则缓存容量 + private void evaluateRuleCacheCapacity() { + Integer capacity = liteflowConfig.getRuleCacheCapacity(); + // 容量不足chain总数的30%给予警告 + int chainNum = FlowBus.getChainMap().size(); + double threshold = chainNum * 0.3; + if (capacity < threshold) { + LOG.warn("The rule cache capacity {} is too small, it is recommended to be greater than 30% of the number of chains", capacity); + } } } \ No newline at end of file diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java index 37fa4625c..427478046 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java @@ -260,9 +260,6 @@ public class Chain implements Executable{ this.isCompiled = true; // 移除临时chain FlowBus.removeChain(tempChainId); -// if (true) { -// throw new RuntimeException("test..."); -// } if (CollUtil.isEmpty(tempConditionList)) { throw new FlowSystemException("no conditionList in this chain[" + chainId + "]"); From 3e3175fdb10c08445de68bd9f2204f709cf3876a Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sat, 22 Mar 2025 17:39:12 +0800 Subject: [PATCH 26/34] =?UTF-8?q?feature=20#IAY66T=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/yomahub/liteflow/core/FlowExecutor.java | 8 ++++++-- .../com/yomahub/liteflow/flow/element/Chain.java | 13 +++++++------ .../liteflow/lifecycle/impl/RuleCacheLifeCycle.java | 7 +++++-- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index 9f247c324..1e2ff507c 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -661,7 +661,10 @@ public class FlowExecutor { boolean exist = lifeCycleList.stream() .anyMatch(lifeCycle -> lifeCycle instanceof RuleCacheLifeCycle); if (!exist) { - RuleCacheLifeCycle.initIfAbsent(capacity); + boolean success = RuleCacheLifeCycle.initIfAbsent(capacity); + if (!success) { + throw new FlowExecutorNotInitException("Initialization of RuleCacheLifeCycle failed"); + } LifeCycleHolder.addLifeCycle(RuleCacheLifeCycle.getLifeCycle()); } @@ -679,7 +682,8 @@ public class FlowExecutor { int chainNum = FlowBus.getChainMap().size(); double threshold = chainNum * 0.3; if (capacity < threshold) { - LOG.warn("The rule cache capacity {} is too small, it is recommended to be greater than 30% of the number of chains", capacity); + LOG.warn("The rule cache capacity {} is too small, the current total number of chains is {}, " + +"it is recommended to be greater than 30% of the number of chains", capacity, chainNum); } } } \ No newline at end of file diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java index 427478046..7060e798a 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java @@ -11,6 +11,7 @@ package com.yomahub.liteflow.flow.element; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.StrUtil; import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder; import com.yomahub.liteflow.common.ChainConstant; import com.yomahub.liteflow.enums.ExecuteableTypeEnum; @@ -108,10 +109,10 @@ public class Chain implements Executable{ // 因为在正式执行condition之前,this.conditionList有可能被其他线程置空 // 比如,该chain在规则缓存中被淘汰 List conditionListRef = this.conditionList; - // 但在编译后到拿到引用之前,this.conditionList可能已经被置空了 + // 但在编译后到拿到引用之前,this.conditionList还是有可能已经被置空了 if (CollUtil.isEmpty(conditionListRef)) { // 如果conditionListRef为空, - // 构建临时conditionList确保本次一定可以执行 + // 尝试构建临时conditionList确保本次一定可以执行 conditionListRef = buildTemporaryConditionList(); } Slot slot = DataBus.getSlot(slotIndex); @@ -248,6 +249,10 @@ public class Chain implements Executable{ // 构建临时的ConditionList private List buildTemporaryConditionList() { + if (StrUtil.isBlank(el)) { + // 无法构建 + throw new FlowSystemException("no conditionList in this chain[" + chainId + "]"); + } // 构建临时chain String tempChainId = chainId + "_temp_" + IdUtil.simpleUUID(); Chain tempChain = new Chain(tempChainId); @@ -261,10 +266,6 @@ public class Chain implements Executable{ // 移除临时chain FlowBus.removeChain(tempChainId); - if (CollUtil.isEmpty(tempConditionList)) { - throw new FlowSystemException("no conditionList in this chain[" + chainId + "]"); - } - // 打印警告,可用于排查临时chain与已有chain重名(几乎不可能发生)而将已有chain覆盖的情况 LOG.warn("The conditionList of chain[{}] is empty, " + "temporarily using chain[{}] (now removed) to build it.", chainId, tempChainId); 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 67eb86bc3..52e3dca35 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 @@ -48,7 +48,7 @@ public class RuleCacheLifeCycle implements PostProcessChainExecuteLifeCycle { @Override public void postProcessAfterChainExecute(String chainId, Slot slot) { - // 不在缓存中、或出于非活跃状态,但未被清理 + // 检测是否有不在缓存中、或处于非活跃状态而未被清理的 Chain if (!isActive(chainId) && !isCleaned(chainId)) { cleanChain(chainId); } @@ -155,11 +155,14 @@ public class RuleCacheLifeCycle implements PostProcessChainExecuteLifeCycle { /** * 初始化生命周期实例 * @param capacity 缓存容量 + * @return 成功 true,失败返回 false */ - public synchronized static void initIfAbsent(int capacity) { + public synchronized static boolean initIfAbsent(int capacity) { if (ObjectUtil.isNull(INSTANCE)) { INSTANCE = new RuleCacheLifeCycle(capacity); + return true; } + return false; } /** From a6ac1b0fe58842a03d3ad19a5759463e8c55f476 Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Wed, 18 Jun 2025 22:43:37 +0800 Subject: [PATCH 27/34] =?UTF-8?q?feature=20#IAY66T=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/yomahub/liteflow/flow/element/Chain.java | 2 -- .../yomahub/liteflow/lifecycle/impl/RuleCacheLifeCycle.java | 2 +- .../com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java | 3 --- .../yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java | 2 -- .../liteflow/test/ruleCache/RuleCacheSpringbootTest.java | 2 -- .../yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java | 2 -- 6 files changed, 1 insertion(+), 12 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java index 698b3c0f7..c0fb2fc1f 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java @@ -269,8 +269,6 @@ public class Chain implements Executable{ LiteFlowChainELBuilder.buildUnCompileChain(tempChain); List tempConditionList = tempChain.getConditionList(); - this.conditionList = tempChain.getConditionList(); - this.isCompiled = true; // 移除临时chain FlowBus.removeChain(tempChainId); 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 52e3dca35..40ea5ecc5 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 @@ -19,7 +19,7 @@ import java.util.List; /** * Chain 缓存处理 * @author DaleLee - * @since 2.13.1 + * @since 2.13.3 */ public class RuleCacheLifeCycle implements PostProcessChainExecuteLifeCycle { /** diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java index 1dedac580..fa5e2ff96 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java @@ -10,8 +10,6 @@ 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.PostProcessChainExecuteLifeCycle; import com.yomahub.liteflow.lifecycle.impl.RuleCacheLifeCycle; import com.yomahub.liteflow.property.LiteflowConfig; import com.yomahub.liteflow.test.BaseTest; @@ -21,7 +19,6 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import javax.annotation.Resource; import java.util.HashSet; import java.util.List; import java.util.Random; diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java index 392e70de7..4e93b998e 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java @@ -9,8 +9,6 @@ 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.PostProcessChainExecuteLifeCycle; import com.yomahub.liteflow.lifecycle.impl.RuleCacheLifeCycle; import com.yomahub.liteflow.test.BaseTest; import org.checkerframework.checker.nullness.qual.NonNull; 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 1611bb65d..3d9b89e21 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 @@ -9,8 +9,6 @@ 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.PostProcessChainExecuteLifeCycle; import com.yomahub.liteflow.lifecycle.impl.RuleCacheLifeCycle; import com.yomahub.liteflow.test.BaseTest; import org.checkerframework.checker.nullness.qual.NonNull; diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java index f76a1bc1a..2f4b81eca 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java @@ -9,8 +9,6 @@ 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.PostProcessChainExecuteLifeCycle; import com.yomahub.liteflow.lifecycle.impl.RuleCacheLifeCycle; import com.yomahub.liteflow.test.BaseTest; import org.checkerframework.checker.nullness.qual.NonNull; From 8be57bed2793c6e9bf0023589d5a47adddb8a63d Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Mon, 7 Jul 2025 22:50:40 +0800 Subject: [PATCH 28/34] =?UTF-8?q?feature=20#IAY66T=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/yomahub/liteflow/flow/element/Chain.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java index c3c5faa3d..509234352 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java @@ -273,13 +273,12 @@ public class Chain implements Executable{ tempChain.setCompiled(false); LiteFlowChainELBuilder.buildUnCompileChain(tempChain); - List tempConditionList = tempChain.getConditionList(); // 移除临时chain FlowBus.removeChain(tempChainId); // 打印警告,可用于排查临时chain与已有chain重名(几乎不可能发生)而将已有chain覆盖的情况 LOG.warn("The conditionList of chain[{}] is empty, " + "temporarily using chain[{}] (now removed) to build it.", chainId, tempChainId); - return tempConditionList; + return tempChain.getConditionList(); } } From 851c3f908b167899250380f4442cf99461b2a9fe Mon Sep 17 00:00:00 2001 From: "everywhere.z" Date: Fri, 18 Jul 2025 17:12:00 +0800 Subject: [PATCH 29/34] =?UTF-8?q?QLExpress=20=E5=8D=87=E7=BA=A7=E5=88=B03.?= =?UTF-8?q?3.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1e8b2e321..089f9d001 100644 --- a/pom.xml +++ b/pom.xml @@ -58,7 +58,7 @@ 0.10 0.7.3 1.4.4 - 3.3.2 + 3.3.4 3.0.8 22.0.0 1.14.10 From 5186e9f5ce45dc227421a79961b3c447abfcb77b Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sun, 20 Jul 2025 15:17:25 +0800 Subject: [PATCH 30/34] =?UTF-8?q?feature=20#IAY66T=20=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E4=B8=B4=E6=97=B6chain=E6=9E=84=E5=BB=BA=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/flow/element/Chain.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java index 939954109..0b16c49d5 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/element/Chain.java @@ -10,7 +10,7 @@ package com.yomahub.liteflow.flow.element; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.BooleanUtil; -import cn.hutool.crypto.digest.MD5; +import cn.hutool.core.util.ObjectUtil; import com.alibaba.ttl.TransmittableThreadLocal; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; @@ -23,6 +23,7 @@ import com.yomahub.liteflow.flow.FlowBus; import com.yomahub.liteflow.lifecycle.LifeCycleHolder; import com.yomahub.liteflow.log.LFLog; import com.yomahub.liteflow.log.LFLoggerManager; +import com.yomahub.liteflow.meta.LiteflowMetaOperator; import com.yomahub.liteflow.slot.DataBus; import com.yomahub.liteflow.slot.Slot; import com.yomahub.liteflow.util.ElRegexUtil; @@ -280,14 +281,16 @@ public class Chain implements Executable { } // 构建临时chain String tempChainId = chainId + "_temp_" + IdUtil.simpleUUID(); - Chain tempChain = new Chain(tempChainId); - tempChain.setEl(el); - tempChain.setCompiled(false); + // 使用LiteFlowChainELBuilder创建chain,为了设置md5 + LiteFlowChainELBuilder.createChain() + .setChainId(tempChainId) + .setEL(el) + .build(); + // 当前模式可能为PARSE_ONE_ON_FIRST_EXEC,所以临时chain可能未编译 + Chain tempChain = LiteflowMetaOperator.getChain(tempChainId); LiteFlowChainELBuilder.buildUnCompileChain(tempChain); - // 移除临时chain - FlowBus.removeChain(tempChainId); - + LiteflowMetaOperator.removeChain(tempChainId); // 打印警告,可用于排查临时chain与已有chain重名(几乎不可能发生)而将已有chain覆盖的情况 LOG.warn("The conditionList of chain[{}] is empty, " + "temporarily using chain[{}] (now removed) to build it.", chainId, tempChainId); From c7afb6174a4037013393a47139edcbd61f2aa8d0 Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sun, 20 Jul 2025 16:35:30 +0800 Subject: [PATCH 31/34] =?UTF-8?q?feature=20#IAY66T=20=E7=AE=80=E5=8C=96cha?= =?UTF-8?q?in=E7=8A=B6=E6=80=81=E8=A1=A8=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lifecycle/impl/RuleCacheLifeCycle.java | 40 +++++++------------ 1 file changed, 15 insertions(+), 25 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 40ea5ecc5..4255b984e 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 @@ -43,7 +43,7 @@ public class RuleCacheLifeCycle implements PostProcessChainExecuteLifeCycle { public void postProcessBeforeChainExecute(String chainId, Slot slot) { // 记录 chainId 在缓存中 // 初始状态为 ACTIVE - cache.get(chainId, key -> new ChainState(State.ACTIVE)); + cache.get(chainId, key -> ChainState.newActiveState()); } @Override @@ -54,39 +54,29 @@ public class RuleCacheLifeCycle implements PostProcessChainExecuteLifeCycle { } } - /** - * Chain 状态枚举 - */ - public enum State { - /** - * 活跃状态 - */ - ACTIVE, - /** - * 非活跃状态 (处于淘汰流程中) - */ - INACTIVE - } - /** * Chain 在缓存中状态 */ public static class ChainState { /** - * Chain 状态 + * Chain 活跃状态 */ - private State state; + private volatile boolean active; - public ChainState(State state) { - this.state = state; + public ChainState(boolean active) { + this.active = active; } - public State getState() { - return state; + public boolean isActive() { + return active; } - public void setState(State state) { - this.state = state; + public void setActive(boolean active) { + this.active = active; + } + + public static ChainState newActiveState() { + return new ChainState(true); } } @@ -98,7 +88,7 @@ public class RuleCacheLifeCycle implements PostProcessChainExecuteLifeCycle { @Override public void onRemoval(@Nullable String chainId, @Nullable ChainState chainState, @NonNull RemovalCause removalCause) { if (ObjectUtil.isNotNull(chainState)) { - chainState.setState(State.INACTIVE); + chainState.setActive(false); } cleanChain(chainId); } @@ -134,7 +124,7 @@ public class RuleCacheLifeCycle implements PostProcessChainExecuteLifeCycle { private boolean isActive(String chainId) { ChainState chainState = cache.getIfPresent(chainId); return ObjectUtil.isNotNull(chainState) - && State.ACTIVE.equals(chainState.getState()); + && chainState.isActive(); } /** From 7714ddf37e07c8e70a8d7c05a94ff98ff6fe9ae8 Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sat, 26 Jul 2025 23:25:09 +0800 Subject: [PATCH 32/34] =?UTF-8?q?feature=20#IAY66T=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E9=A1=B9=E5=90=8D=E7=A7=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/core/FlowExecutor.java | 44 ++++++++++--------- ...ifeCycle.java => ChainCacheLifeCycle.java} | 12 ++--- .../liteflow/property/LiteflowConfig.java | 29 ++++++------ .../config/LiteflowAutoConfiguration.java | 4 +- .../solon/config/LiteflowProperty.java | 12 ++--- .../META-INF/liteflow-default.properties | 3 +- .../liteflow/springboot/LiteflowProperty.java | 14 +++--- .../LiteflowPropertyAutoConfiguration.java | 4 +- .../META-INF/liteflow-default.properties | 4 +- .../ChainCacheTest.java} | 36 ++++++++------- .../{ruleCache => chainCache}/cmp/ACmp.java | 2 +- .../{ruleCache => chainCache}/cmp/BCmp.java | 2 +- .../{ruleCache => chainCache}/cmp/CCmp.java | 2 +- .../{ruleCache => chainCache}/cmp/XCmp.java | 2 +- .../{ruleCache => chainCache}/flow.el.xml | 8 ++-- .../ChainCacheSolonTest.java} | 30 ++++++------- .../{ruleCache => chainCache}/cmp/ACmp.java | 2 +- .../{ruleCache => chainCache}/cmp/BCmp.java | 2 +- .../{ruleCache => chainCache}/cmp/CCmp.java | 2 +- .../{ruleCache => chainCache}/cmp/XCmp.java | 2 +- .../chainCache/application.properties | 4 ++ .../{ruleCache => chainCache}/flow.el.xml | 0 .../ruleCache/application.properties | 3 -- .../ChainCacheSpringbootTest.java} | 34 +++++++------- .../{ruleCache => chainCache}/cmp/ACmp.java | 2 +- .../liteflow/test/chainCache}/cmp/BCmp.java | 2 +- .../{ruleCache => chainCache}/cmp/CCmp.java | 2 +- .../{ruleCache => chainCache}/cmp/XCmp.java | 2 +- .../chainCache/application.properties | 4 ++ .../{ruleCache => chainCache}/flow.el.xml | 0 .../ruleCache/application.properties | 3 -- .../ChainCacheSpringTest.java} | 30 ++++++------- .../{ruleCache => chainCache}/cmp/ACmp.java | 2 +- .../liteflow/test/chainCache}/cmp/BCmp.java | 2 +- .../{ruleCache => chainCache}/cmp/CCmp.java | 2 +- .../{ruleCache => chainCache}/cmp/XCmp.java | 2 +- .../{ruleCache => chainCache}/application.xml | 9 ++-- .../{ruleCache => chainCache}/flow.el.xml | 0 38 files changed, 166 insertions(+), 153 deletions(-) rename liteflow-core/src/main/java/com/yomahub/liteflow/lifecycle/impl/{RuleCacheLifeCycle.java => ChainCacheLifeCycle.java} (93%) rename liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/{ruleCache/RuleCacheTest.java => chainCache/ChainCacheTest.java} (89%) rename liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/{ruleCache => chainCache}/cmp/ACmp.java (86%) rename liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/{ruleCache => chainCache}/cmp/BCmp.java (86%) rename liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/{ruleCache => chainCache}/cmp/CCmp.java (86%) rename liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/{ruleCache => chainCache}/cmp/XCmp.java (80%) rename liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/{ruleCache => chainCache}/flow.el.xml (69%) rename liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/{ruleCache/RuleCacheSolonTest.java => chainCache/ChainCacheSolonTest.java} (90%) rename liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/{ruleCache => chainCache}/cmp/ACmp.java (88%) rename liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/{ruleCache => chainCache}/cmp/BCmp.java (88%) rename liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/{ruleCache => chainCache}/cmp/CCmp.java (88%) rename liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/{ruleCache => chainCache}/cmp/XCmp.java (84%) create mode 100644 liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/chainCache/application.properties rename liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/{ruleCache => chainCache}/flow.el.xml (100%) delete mode 100644 liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/ruleCache/application.properties rename liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/{ruleCache/RuleCacheSpringbootTest.java => chainCache/ChainCacheSpringbootTest.java} (89%) rename liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/{ruleCache => chainCache}/cmp/ACmp.java (88%) rename liteflow-testcase-el/{liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache => liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/chainCache}/cmp/BCmp.java (88%) rename liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/{ruleCache => chainCache}/cmp/CCmp.java (88%) rename liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/{ruleCache => chainCache}/cmp/XCmp.java (84%) create mode 100644 liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/chainCache/application.properties rename liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/{ruleCache => chainCache}/flow.el.xml (100%) delete mode 100644 liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/application.properties rename liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/{ruleCache/RuleCacheSpringTest.java => chainCache/ChainCacheSpringTest.java} (91%) rename liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/{ruleCache => chainCache}/cmp/ACmp.java (88%) rename liteflow-testcase-el/{liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache => liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/chainCache}/cmp/BCmp.java (88%) rename liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/{ruleCache => chainCache}/cmp/CCmp.java (88%) rename liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/{ruleCache => chainCache}/cmp/XCmp.java (84%) rename liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/{ruleCache => chainCache}/application.xml (78%) rename liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/{ruleCache => chainCache}/flow.el.xml (100%) diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java index 40eff4c49..7555e2245 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/core/FlowExecutor.java @@ -23,7 +23,7 @@ import com.yomahub.liteflow.exception.*; import com.yomahub.liteflow.flow.FlowBus; import com.yomahub.liteflow.flow.LiteflowResponse; import com.yomahub.liteflow.lifecycle.PostProcessChainExecuteLifeCycle; -import com.yomahub.liteflow.lifecycle.impl.RuleCacheLifeCycle; +import com.yomahub.liteflow.lifecycle.impl.ChainCacheLifeCycle; import com.yomahub.liteflow.flow.element.Chain; import com.yomahub.liteflow.flow.element.Node; import com.yomahub.liteflow.flow.element.Rollbackable; @@ -106,9 +106,9 @@ public class FlowExecutor { } // 规则缓存 - if (isStart && liteflowConfig.getRuleCacheEnabled()) { + if (isStart && liteflowConfig.getChainCacheEnabled()) { // 放到解析节点后,是因为要根据节点数量判断缓存大小设置是否合理 - initRuleCache(); + initChainCache(); } String ruleSource = liteflowConfig.getRuleSource(); @@ -239,8 +239,8 @@ public class FlowExecutor { } // 初始化或reload时,评估规则缓存容量大小 - if (liteflowConfig.getRuleCacheEnabled()) { - evaluateRuleCacheCapacity(); + if (liteflowConfig.getChainCacheEnabled()) { + evaluateChainCacheCapacity(); } } @@ -678,40 +678,42 @@ public class FlowExecutor { return resultSlotList; } - private void initRuleCache() { + private void initChainCache() { + // 启动chain缓存必须使用 PARSE_ONE_ON_FIRST_EXEC 模式 + if (!ParseModeEnum.PARSE_ONE_ON_FIRST_EXEC.equals(liteflowConfig.getParseMode())) { + LOG.warn("The parse mode is not PARSE_ONE_ON_FIRST_EXE, so the chain cache cannot be enabled."); + return; + } // 容量不能小于等于0 - Integer capacity = liteflowConfig.getRuleCacheCapacity(); + Integer capacity = liteflowConfig.getChainCacheCapacity(); if (ObjectUtil.isNull(capacity) || capacity <= 0) { - throw new ConfigErrorException("The rule cache capacity must be greater than 0"); + throw new ConfigErrorException("The chain cache capacity must be greater than 0"); } // 添加规则缓存生命周期 List lifeCycleList = LifeCycleHolder.getPostProcessChainExecuteLifeCycleList(); boolean exist = lifeCycleList.stream() - .anyMatch(lifeCycle -> lifeCycle instanceof RuleCacheLifeCycle); + .anyMatch(lifeCycle -> lifeCycle instanceof ChainCacheLifeCycle); if (!exist) { - boolean success = RuleCacheLifeCycle.initIfAbsent(capacity); + boolean success = ChainCacheLifeCycle.initIfAbsent(capacity); if (!success) { - throw new FlowExecutorNotInitException("Initialization of RuleCacheLifeCycle failed"); + throw new FlowExecutorNotInitException("Initialization of ChainCacheLifeCycle failed"); } - LifeCycleHolder.addLifeCycle(RuleCacheLifeCycle.getLifeCycle()); - } - - // 执行时才解析chain - if (!ParseModeEnum.PARSE_ONE_ON_FIRST_EXEC.equals(liteflowConfig.getParseMode())) { - liteflowConfig.setParseMode(ParseModeEnum.PARSE_ONE_ON_FIRST_EXEC); - LOG.warn("The rule cache is enabled, so the parse mode is forcibly set to PARSE_ONE_ON_FIRST_EXE."); + LifeCycleHolder.addLifeCycle(ChainCacheLifeCycle.getLifeCycle()); } } // 评估规则缓存容量 - private void evaluateRuleCacheCapacity() { - Integer capacity = liteflowConfig.getRuleCacheCapacity(); + private void evaluateChainCacheCapacity() { + if (!ParseModeEnum.PARSE_ONE_ON_FIRST_EXEC.equals(liteflowConfig.getParseMode())) { + return; + } + Integer capacity = liteflowConfig.getChainCacheCapacity(); // 容量不足chain总数的30%给予警告 int chainNum = FlowBus.getChainMap().size(); double threshold = chainNum * 0.3; if (capacity < threshold) { - LOG.warn("The rule cache capacity {} is too small, the current total number of chains is {}, " + LOG.warn("The chain cache capacity {} is too small, the current total number of chains is {}, " +"it is recommended to be greater than 30% of the number of chains", capacity, chainNum); } } 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/ChainCacheLifeCycle.java similarity index 93% rename from liteflow-core/src/main/java/com/yomahub/liteflow/lifecycle/impl/RuleCacheLifeCycle.java rename to liteflow-core/src/main/java/com/yomahub/liteflow/lifecycle/impl/ChainCacheLifeCycle.java index 4255b984e..5bc68e3a0 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/ChainCacheLifeCycle.java @@ -17,11 +17,11 @@ import org.checkerframework.checker.nullness.qual.Nullable; import java.util.List; /** - * Chain 缓存处理 + * Chain 缓存生命周期 * @author DaleLee * @since 2.13.3 */ -public class RuleCacheLifeCycle implements PostProcessChainExecuteLifeCycle { +public class ChainCacheLifeCycle implements PostProcessChainExecuteLifeCycle { /** * 缓存 */ @@ -30,9 +30,9 @@ public class RuleCacheLifeCycle implements PostProcessChainExecuteLifeCycle { /** * 实例 */ - private static RuleCacheLifeCycle INSTANCE; + private static ChainCacheLifeCycle INSTANCE; - private RuleCacheLifeCycle(int capacity) { + private ChainCacheLifeCycle(int capacity) { this.cache = Caffeine.newBuilder() .maximumSize(capacity) .evictionListener(new ChainRemovalListener()) @@ -149,7 +149,7 @@ public class RuleCacheLifeCycle implements PostProcessChainExecuteLifeCycle { */ public synchronized static boolean initIfAbsent(int capacity) { if (ObjectUtil.isNull(INSTANCE)) { - INSTANCE = new RuleCacheLifeCycle(capacity); + INSTANCE = new ChainCacheLifeCycle(capacity); return true; } return false; @@ -159,7 +159,7 @@ public class RuleCacheLifeCycle implements PostProcessChainExecuteLifeCycle { * 获取生命周期实例 * @return lifeCycle */ - public static RuleCacheLifeCycle getLifeCycle() { + public static ChainCacheLifeCycle getLifeCycle() { return INSTANCE; } } diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java b/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java index 25d8abedf..859b6b1ef 100644 --- a/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java +++ b/liteflow-core/src/main/java/com/yomahub/liteflow/property/LiteflowConfig.java @@ -116,11 +116,11 @@ public class LiteflowConfig { // instance id 生成器 private String instanceIdGeneratorClass; - // 是否启用规则缓存 - private Boolean ruleCacheEnabled; + // 是否启用chain缓存 + private Boolean chainCacheEnabled; - // 规则缓存容量 - private Integer ruleCacheCapacity; + // chain缓存容量 + private Integer chainCacheCapacity; public Boolean getEnableMonitorFile() { return enableMonitorFile; @@ -502,22 +502,25 @@ public class LiteflowConfig { this.instanceIdGeneratorClass = instanceIdGeneratorClass; } - public Boolean getRuleCacheEnabled() { - if (ObjectUtil.isNull(ruleCacheEnabled)) { + public Boolean getChainCacheEnabled() { + if (ObjectUtil.isNull(chainCacheEnabled)) { return Boolean.FALSE; } - return ruleCacheEnabled; + return chainCacheEnabled; } - public void setRuleCacheEnabled(Boolean ruleCacheEnabled) { - this.ruleCacheEnabled = ruleCacheEnabled; + public void setChainCacheEnabled(Boolean chainCacheEnabled) { + this.chainCacheEnabled = chainCacheEnabled; } - public Integer getRuleCacheCapacity() { - return ruleCacheCapacity; + public Integer getChainCacheCapacity() { + if (ObjectUtil.isNull(chainCacheCapacity)) { + return 10000; + } + return chainCacheCapacity; } - public void setRuleCacheCapacity(Integer ruleCacheCapacity) { - this.ruleCacheCapacity = ruleCacheCapacity; + public void setChainCacheCapacity(Integer chainCacheCapacity) { + this.chainCacheCapacity = chainCacheCapacity; } } diff --git a/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowAutoConfiguration.java b/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowAutoConfiguration.java index 932a403c0..36c5cbae7 100644 --- a/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowAutoConfiguration.java +++ b/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowAutoConfiguration.java @@ -51,8 +51,8 @@ public class LiteflowAutoConfiguration { liteflowConfig.setGlobalThreadPoolQueueSize(property.getGlobalThreadPoolQueueSize()); liteflowConfig.setWhenThreadPoolIsolate(property.getWhenThreadPoolIsolate()); liteflowConfig.setEnableNodeInstanceId(property.isEnableNodeInstanceId()); - liteflowConfig.setRuleCacheEnabled(property.getRuleCache().isEnabled()); - liteflowConfig.setRuleCacheCapacity(property.getRuleCache().getCapacity()); + liteflowConfig.setChainCacheEnabled(property.getChainCache().isEnabled()); + liteflowConfig.setChainCacheCapacity(property.getChainCache().getCapacity()); return liteflowConfig; } diff --git a/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowProperty.java b/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowProperty.java index fc65cac33..f6aa0e50c 100644 --- a/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowProperty.java +++ b/liteflow-solon-plugin/src/main/java/com/yomahub/liteflow/solon/config/LiteflowProperty.java @@ -102,9 +102,9 @@ public class LiteflowProperty { private boolean enableNodeInstanceId; // 规则缓存配置 - private RuleCacheProperty ruleCache; + private ChainCacheProperty chainCache; - public static class RuleCacheProperty { + public static class ChainCacheProperty { // 是否启用规则缓存 private Boolean enabled; @@ -369,11 +369,11 @@ public class LiteflowProperty { this.enableNodeInstanceId = enableNodeInstanceId; } - public RuleCacheProperty getRuleCache() { - return ruleCache; + public ChainCacheProperty getChainCache() { + return chainCache; } - public void setRuleCache(RuleCacheProperty ruleCache) { - this.ruleCache = ruleCache; + public void setChainCache(ChainCacheProperty chainCache) { + this.chainCache = chainCache; } } diff --git a/liteflow-solon-plugin/src/main/resources/META-INF/liteflow-default.properties b/liteflow-solon-plugin/src/main/resources/META-INF/liteflow-default.properties index 8bc5b482e..820d04aba 100644 --- a/liteflow-solon-plugin/src/main/resources/META-INF/liteflow-default.properties +++ b/liteflow-solon-plugin/src/main/resources/META-INF/liteflow-default.properties @@ -19,4 +19,5 @@ liteflow.global-thread-pool-size=16 liteflow.global-thread-pool-queue-size=512 liteflow.global-thread-pool-executor-class=com.yomahub.liteflow.thread.LiteFlowDefaultGlobalExecutorBuilder liteflow.enable-node-instance-id=false -liteflow.rule-cache.enabled=false +liteflow.chain-cache.enabled=false +liteflow.chain-cache.capacity=10000 diff --git a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java index 6c08c5a4d..eff05a112 100644 --- a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java +++ b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/LiteflowProperty.java @@ -102,13 +102,13 @@ public class LiteflowProperty { // 规则缓存配置 @NestedConfigurationProperty - private RuleCacheProperty ruleCache; + private ChainCacheProperty chainCache; - public static class RuleCacheProperty { + public static class ChainCacheProperty { // 是否启用规则缓存 private Boolean enabled; - // 规则缓存容量 + // chain缓存容量 private Integer capacity; public Boolean isEnabled() { @@ -360,11 +360,11 @@ public class LiteflowProperty { this.enableNodeInstanceId = enableNodeInstanceId; } - public RuleCacheProperty getRuleCache() { - return ruleCache; + public ChainCacheProperty getChainCache() { + return chainCache; } - public void setRuleCache(RuleCacheProperty ruleCache) { - this.ruleCache = ruleCache; + public void setChainCache(ChainCacheProperty chainCache) { + this.chainCache = chainCache; } } diff --git a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java index 71a6756d2..26a28059a 100644 --- a/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java +++ b/liteflow-spring-boot-starter/src/main/java/com/yomahub/liteflow/springboot/config/LiteflowPropertyAutoConfiguration.java @@ -53,8 +53,8 @@ public class LiteflowPropertyAutoConfiguration { liteflowConfig.setGlobalThreadPoolQueueSize(property.getGlobalThreadPoolQueueSize()); liteflowConfig.setGlobalThreadPoolSize(property.getGlobalThreadPoolSize()); liteflowConfig.setEnableNodeInstanceId(property.isEnableNodeInstanceId()); - liteflowConfig.setRuleCacheEnabled(property.getRuleCache().isEnabled()); - liteflowConfig.setRuleCacheCapacity(property.getRuleCache().getCapacity()); + liteflowConfig.setChainCacheEnabled(property.getChainCache().isEnabled()); + liteflowConfig.setChainCacheCapacity(property.getChainCache().getCapacity()); return liteflowConfig; } diff --git a/liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties b/liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties index 8b0eed331..ca67a1d37 100644 --- a/liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties +++ b/liteflow-spring-boot-starter/src/main/resources/META-INF/liteflow-default.properties @@ -24,5 +24,7 @@ liteflow.global-thread-pool-size=64 liteflow.global-thread-pool-queue-size=512 liteflow.global-thread-pool-executor-class=com.yomahub.liteflow.thread.LiteFlowDefaultGlobalExecutorBuilder liteflow.enable-node-instance-id=false -liteflow.rule-cache.enabled=false +liteflow.chain-cache.enabled=false +liteflow.chain-cache.capacity=10000 + diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/chainCache/ChainCacheTest.java similarity index 89% rename from liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java rename to liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/chainCache/ChainCacheTest.java index fa5e2ff96..6355deaec 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/chainCache/ChainCacheTest.java @@ -1,16 +1,17 @@ -package com.yomahub.liteflow.test.ruleCache; +package com.yomahub.liteflow.test.chainCache; 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.core.FlowExecutorHolder; +import com.yomahub.liteflow.enums.ParseModeEnum; import com.yomahub.liteflow.exception.ChainNotFoundException; 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.impl.RuleCacheLifeCycle; +import com.yomahub.liteflow.lifecycle.impl.ChainCacheLifeCycle; import com.yomahub.liteflow.property.LiteflowConfig; import com.yomahub.liteflow.test.BaseTest; import org.checkerframework.checker.nullness.qual.NonNull; @@ -27,19 +28,20 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; /** - * 非Spring环境下的规则缓存测试 + * 非Spring环境下的chain缓存测试 * @author DaleLee */ -public class RuleCacheTest extends BaseTest { +public class ChainCacheTest extends BaseTest { private static FlowExecutor flowExecutor; @BeforeAll public static void init() { LiteflowConfig config = new LiteflowConfig(); - config.setRuleSource("ruleCache/flow.el.xml"); - config.setRuleCacheEnabled(true); - config.setRuleCacheCapacity(5); + config.setRuleSource("chainCache/flow.el.xml"); + config.setChainCacheEnabled(true); + config.setChainCacheCapacity(5); + config.setParseMode(ParseModeEnum.PARSE_ONE_ON_FIRST_EXEC); flowExecutor = FlowExecutorHolder.loadInstance(config); } @@ -47,14 +49,14 @@ public class RuleCacheTest extends BaseTest { public void reload() { flowExecutor.reloadRule(); // 清空缓存 - Cache cache = getCache(); + Cache cache = getCache(); cache.invalidateAll(); cache.cleanUp(); } // 测试chain被淘汰 @Test - public void testRuleCache1() { + public void testChainCache1() { // 加满缓存 loadCache(); // 缓存快照 @@ -72,7 +74,7 @@ public class RuleCacheTest extends BaseTest { // 测试缓存数量上限(串行) @Test - public void testRuleCache2() { + public void testChainCache2() { // 确保至少执行过5个不同的chain loadCache(); // 随机执行chain @@ -100,7 +102,7 @@ public class RuleCacheTest extends BaseTest { // 测试缓存数量上限(并行) @Test - public void testRuleCache3() { + public void testChainCache3() { loadCache(); Random random = new Random(); List> futureList = CollUtil.newArrayList(); @@ -137,7 +139,7 @@ public class RuleCacheTest extends BaseTest { // 测试开启规则缓存后,进入缓存的chain可以正常被更新 @Test - public void testRuleCache4() { + public void testChainCache4() { loadCache(); // 缓存快照 HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); @@ -163,7 +165,7 @@ public class RuleCacheTest extends BaseTest { // 测试开启规则缓存后,进入缓存的chain被移除后无法执行 @Test - public void testRuleCache5() { + public void testChainCache5() { loadCache(); // 缓存快照 HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); @@ -184,7 +186,7 @@ public class RuleCacheTest extends BaseTest { // 测试并发下,正在执行的chain的condition被清理但仍能执行 @Test - public void testRuleCache6() throws InterruptedException { + public void testChainCache6() throws InterruptedException { // 模拟清空编译好的chain Thread thread = new Thread(()-> { Chain chain1 = FlowBus.getChain("chain1"); @@ -218,14 +220,14 @@ public class RuleCacheTest extends BaseTest { Assertions.assertNull(chain.getConditionList()); } - public Cache getCache() { - return RuleCacheLifeCycle.getLifeCycle().getCache(); + public Cache getCache() { + return ChainCacheLifeCycle.getLifeCycle().getCache(); } // 获得淘汰的chain,传入淘汰前的chain集合 // 确保只有一个被淘汰时使用 String getEvictedChain(Set set) { - Cache cache = getCache(); + Cache cache = getCache(); cache.cleanUp(); Set<@NonNull String> strings = cache.asMap().keySet(); set.removeAll(strings); diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/ACmp.java similarity index 86% rename from liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java rename to liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/ACmp.java index 1681cc291..8d6b10e39 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/ACmp.java @@ -5,7 +5,7 @@ * @email weenyc31@163.com * @Date 2020/4/1 */ -package com.yomahub.liteflow.test.ruleCache.cmp; +package com.yomahub.liteflow.test.chainCache.cmp; import com.yomahub.liteflow.core.NodeComponent; diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/BCmp.java similarity index 86% rename from liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java rename to liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/BCmp.java index af5a966ab..7e7cc3913 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/BCmp.java @@ -5,7 +5,7 @@ * @email weenyc31@163.com * @Date 2020/4/1 */ -package com.yomahub.liteflow.test.ruleCache.cmp; +package com.yomahub.liteflow.test.chainCache.cmp; import com.yomahub.liteflow.core.NodeComponent; diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/CCmp.java similarity index 86% rename from liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java rename to liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/CCmp.java index b64d73f1b..4c828a4b9 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/CCmp.java @@ -5,7 +5,7 @@ * @email weenyc31@163.com * @Date 2020/4/1 */ -package com.yomahub.liteflow.test.ruleCache.cmp; +package com.yomahub.liteflow.test.chainCache.cmp; import com.yomahub.liteflow.core.NodeComponent; diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/XCmp.java similarity index 80% rename from liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java rename to liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/XCmp.java index 61e48503d..d4c343a9b 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/XCmp.java @@ -1,4 +1,4 @@ -package com.yomahub.liteflow.test.ruleCache.cmp; +package com.yomahub.liteflow.test.chainCache.cmp; import com.yomahub.liteflow.core.NodeBooleanComponent; diff --git a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/ruleCache/flow.el.xml b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/chainCache/flow.el.xml similarity index 69% rename from liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/ruleCache/flow.el.xml rename to liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/chainCache/flow.el.xml index 5bfd951f8..7f247d576 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/ruleCache/flow.el.xml +++ b/liteflow-testcase-el/liteflow-testcase-el-nospring/src/test/resources/chainCache/flow.el.xml @@ -1,10 +1,10 @@ - - - - + + + + diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/chainCache/ChainCacheSolonTest.java similarity index 90% rename from liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java rename to liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/chainCache/ChainCacheSolonTest.java index 4e93b998e..f64c5fc4e 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSolonTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/chainCache/ChainCacheSolonTest.java @@ -1,4 +1,4 @@ -package com.yomahub.liteflow.test.ruleCache; +package com.yomahub.liteflow.test.chainCache; import cn.hutool.core.collection.CollUtil; import com.github.benmanes.caffeine.cache.Cache; @@ -9,7 +9,7 @@ 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.impl.RuleCacheLifeCycle; +import com.yomahub.liteflow.lifecycle.impl.ChainCacheLifeCycle; import com.yomahub.liteflow.test.BaseTest; import org.checkerframework.checker.nullness.qual.NonNull; import org.junit.jupiter.api.Assertions; @@ -27,12 +27,12 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; /** - * Solon环境下规则缓存测试 + * Solon环境下chain缓存测试 * @author DaleLee */ @SolonTest -@Import(profiles="classpath:/ruleCache/application.properties") -public class RuleCacheSolonTest extends BaseTest { +@Import(profiles="classpath:/chainCache/application.properties") +public class ChainCacheSolonTest extends BaseTest { @Inject private FlowExecutor flowExecutor; @@ -41,14 +41,14 @@ public class RuleCacheSolonTest extends BaseTest { public void reload() { flowExecutor.reloadRule(); // 清空缓存 - Cache cache = getCache(); + Cache cache = getCache(); cache.invalidateAll(); cache.cleanUp(); } // 测试chain被淘汰 @Test - public void testRuleCache1() { + public void testChainCache1() { // 加满缓存 loadCache(); // 缓存快照 @@ -66,7 +66,7 @@ public class RuleCacheSolonTest extends BaseTest { // 测试缓存数量上限(串行) @Test - public void testRuleCache2() { + public void testChainCache2() { // 确保至少执行过5个不同的chain loadCache(); // 随机执行chain @@ -94,7 +94,7 @@ public class RuleCacheSolonTest extends BaseTest { // 测试缓存数量上限(并行) @Test - public void testRuleCache3() { + public void testChainCache3() { loadCache(); Random random = new Random(); List> futureList = CollUtil.newArrayList(); @@ -131,7 +131,7 @@ public class RuleCacheSolonTest extends BaseTest { // 测试开启规则缓存后,进入缓存的chain可以正常被更新 @Test - public void testRuleCache4() { + public void testChainCache4() { loadCache(); // 缓存快照 HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); @@ -157,7 +157,7 @@ public class RuleCacheSolonTest extends BaseTest { // 测试开启规则缓存后,进入缓存的chain被移除后无法执行 @Test - public void testRuleCache5() { + public void testChainCache5() { loadCache(); // 缓存快照 HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); @@ -178,7 +178,7 @@ public class RuleCacheSolonTest extends BaseTest { // 测试并发下,正在执行的chain的condition被清理但仍能执行 @Test - public void testRuleCache6() throws InterruptedException { + public void testChainCache6() throws InterruptedException { // 模拟清空编译好的chain Thread thread = new Thread(()-> { Chain chain1 = FlowBus.getChain("chain1"); @@ -212,14 +212,14 @@ public class RuleCacheSolonTest extends BaseTest { Assertions.assertNull(chain.getConditionList()); } - public Cache getCache() { - return RuleCacheLifeCycle.getLifeCycle().getCache(); + public Cache getCache() { + return ChainCacheLifeCycle.getLifeCycle().getCache(); } // 获得淘汰的chain,传入淘汰前的chain集合 // 确保只有一个被淘汰时使用 String getEvictedChain(Set set) { - Cache cache = getCache(); + Cache cache = getCache(); cache.cleanUp(); Set<@NonNull String> strings = cache.asMap().keySet(); set.removeAll(strings); diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/ACmp.java similarity index 88% rename from liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java rename to liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/ACmp.java index da4be1512..b45ae448d 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java +++ b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/ACmp.java @@ -5,7 +5,7 @@ * @email weenyc31@163.com * @Date 2020/4/1 */ -package com.yomahub.liteflow.test.ruleCache.cmp; +package com.yomahub.liteflow.test.chainCache.cmp; import com.yomahub.liteflow.core.NodeComponent; import org.noear.solon.annotation.Component; diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/BCmp.java similarity index 88% rename from liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java rename to liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/BCmp.java index 7f957f293..73c4d630d 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java +++ b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/BCmp.java @@ -5,7 +5,7 @@ * @email weenyc31@163.com * @Date 2020/4/1 */ -package com.yomahub.liteflow.test.ruleCache.cmp; +package com.yomahub.liteflow.test.chainCache.cmp; import com.yomahub.liteflow.core.NodeComponent; import org.noear.solon.annotation.Component; diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/CCmp.java similarity index 88% rename from liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java rename to liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/CCmp.java index c49a987e9..033821755 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java +++ b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/CCmp.java @@ -5,7 +5,7 @@ * @email weenyc31@163.com * @Date 2020/4/1 */ -package com.yomahub.liteflow.test.ruleCache.cmp; +package com.yomahub.liteflow.test.chainCache.cmp; import com.yomahub.liteflow.core.NodeComponent; import org.noear.solon.annotation.Component; diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/XCmp.java similarity index 84% rename from liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java rename to liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/XCmp.java index 73b375e01..fddd1a000 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java +++ b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/XCmp.java @@ -1,4 +1,4 @@ -package com.yomahub.liteflow.test.ruleCache.cmp; +package com.yomahub.liteflow.test.chainCache.cmp; import com.yomahub.liteflow.core.NodeBooleanComponent; import org.noear.solon.annotation.Component; diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/chainCache/application.properties b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/chainCache/application.properties new file mode 100644 index 000000000..2f9c44ccc --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/chainCache/application.properties @@ -0,0 +1,4 @@ +liteflow.rule-source=chainCache/flow.el.xml +liteflow.chain-cache.enabled=true +liteflow.chain-cache.capacity=5 +liteflow.parse-mode=PARSE_ONE_ON_FIRST_EXEC \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/ruleCache/flow.el.xml b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/chainCache/flow.el.xml similarity index 100% rename from liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/ruleCache/flow.el.xml rename to liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/chainCache/flow.el.xml diff --git a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/ruleCache/application.properties b/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/ruleCache/application.properties deleted file mode 100644 index cb4066d3c..000000000 --- a/liteflow-testcase-el/liteflow-testcase-el-solon/src/test/resources/ruleCache/application.properties +++ /dev/null @@ -1,3 +0,0 @@ -liteflow.rule-source=ruleCache/flow.el.xml -liteflow.rule-cache.enabled=true -liteflow.rule-cache.capacity=5 \ No newline at end of file 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/chainCache/ChainCacheSpringbootTest.java similarity index 89% rename from liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringbootTest.java rename to liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/chainCache/ChainCacheSpringbootTest.java index 3d9b89e21..31e6e5139 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/chainCache/ChainCacheSpringbootTest.java @@ -1,4 +1,4 @@ -package com.yomahub.liteflow.test.ruleCache; +package com.yomahub.liteflow.test.chainCache; import cn.hutool.core.collection.CollUtil; import com.github.benmanes.caffeine.cache.Cache; @@ -9,7 +9,7 @@ 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.impl.RuleCacheLifeCycle; +import com.yomahub.liteflow.lifecycle.impl.ChainCacheLifeCycle; import com.yomahub.liteflow.test.BaseTest; import org.checkerframework.checker.nullness.qual.NonNull; import org.junit.jupiter.api.Assertions; @@ -29,14 +29,14 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; /** - * Springboot环境下规则缓存测试 + * Springboot环境下chain缓存测试 * @author DaleLee */ -@TestPropertySource(value = "classpath:/ruleCache/application.properties") -@SpringBootTest(classes = RuleCacheSpringbootTest.class) +@TestPropertySource(value = "classpath:/chainCache/application.properties") +@SpringBootTest(classes = ChainCacheSpringbootTest.class) @EnableAutoConfiguration -@ComponentScan({ "com.yomahub.liteflow.test.ruleCache.cmp" }) -public class RuleCacheSpringbootTest extends BaseTest { +@ComponentScan({"com.yomahub.liteflow.test.chainCache.cmp"}) +public class ChainCacheSpringbootTest extends BaseTest { @Resource private FlowExecutor flowExecutor; @@ -44,14 +44,14 @@ public class RuleCacheSpringbootTest extends BaseTest { public void reload() { flowExecutor.reloadRule(); // 清空缓存 - Cache cache = getCache(); + Cache cache = getCache(); cache.invalidateAll(); cache.cleanUp(); } // 测试chain被淘汰 @Test - public void testRuleCache1() { + public void testChainCache1() { // 加满缓存 loadCache(); // 缓存快照 @@ -69,7 +69,7 @@ public class RuleCacheSpringbootTest extends BaseTest { // 测试缓存数量上限(串行) @Test - public void testRuleCache2() { + public void testChainCache2() { // 确保至少执行过5个不同的chain loadCache(); // 随机执行chain @@ -97,7 +97,7 @@ public class RuleCacheSpringbootTest extends BaseTest { // 测试缓存数量上限(并行) @Test - public void testRuleCache3() { + public void testChainCache3() { loadCache(); Random random = new Random(); List> futureList = CollUtil.newArrayList(); @@ -134,7 +134,7 @@ public class RuleCacheSpringbootTest extends BaseTest { // 测试开启规则缓存后,进入缓存的chain可以正常被更新 @Test - public void testRuleCache4() { + public void testChainCache4() { loadCache(); // 缓存快照 HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); @@ -160,7 +160,7 @@ public class RuleCacheSpringbootTest extends BaseTest { // 测试开启规则缓存后,进入缓存的chain被移除后无法执行 @Test - public void testRuleCache5() { + public void testChainCache5() { loadCache(); // 缓存快照 HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); @@ -181,7 +181,7 @@ public class RuleCacheSpringbootTest extends BaseTest { // 测试并发下,正在执行的chain的condition被清理但仍能执行 @Test - public void testRuleCache6() throws InterruptedException { + public void testChainCache6() throws InterruptedException { // 模拟清空编译好的chain Thread thread = new Thread(()-> { Chain chain1 = FlowBus.getChain("chain1"); @@ -215,14 +215,14 @@ public class RuleCacheSpringbootTest extends BaseTest { Assertions.assertNull(chain.getConditionList()); } - public Cache getCache() { - return RuleCacheLifeCycle.getLifeCycle().getCache(); + public Cache getCache() { + return ChainCacheLifeCycle.getLifeCycle().getCache(); } // 获得淘汰的chain,传入淘汰前的chain集合 // 确保只有一个被淘汰时使用 String getEvictedChain(Set set) { - Cache cache = getCache(); + Cache cache = getCache(); cache.cleanUp(); Set<@NonNull String> strings = cache.asMap().keySet(); set.removeAll(strings); diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/ACmp.java similarity index 88% rename from liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java rename to liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/ACmp.java index e5999686e..d943cb205 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/ACmp.java @@ -5,7 +5,7 @@ * @email weenyc31@163.com * @Date 2020/4/1 */ -package com.yomahub.liteflow.test.ruleCache.cmp; +package com.yomahub.liteflow.test.chainCache.cmp; import com.yomahub.liteflow.core.NodeComponent; import org.springframework.stereotype.Component; diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/BCmp.java similarity index 88% rename from liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java rename to liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/BCmp.java index c79f55d47..356750126 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/BCmp.java @@ -5,7 +5,7 @@ * @email weenyc31@163.com * @Date 2020/4/1 */ -package com.yomahub.liteflow.test.ruleCache.cmp; +package com.yomahub.liteflow.test.chainCache.cmp; import com.yomahub.liteflow.core.NodeComponent; import org.springframework.stereotype.Component; diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/CCmp.java similarity index 88% rename from liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java rename to liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/CCmp.java index a5ba32f37..84dedc927 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/CCmp.java @@ -5,7 +5,7 @@ * @email weenyc31@163.com * @Date 2020/4/1 */ -package com.yomahub.liteflow.test.ruleCache.cmp; +package com.yomahub.liteflow.test.chainCache.cmp; import com.yomahub.liteflow.core.NodeComponent; import org.springframework.stereotype.Component; diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/XCmp.java similarity index 84% rename from liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java rename to liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/XCmp.java index 1c71b836c..1f671e9e4 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/XCmp.java @@ -1,4 +1,4 @@ -package com.yomahub.liteflow.test.ruleCache.cmp; +package com.yomahub.liteflow.test.chainCache.cmp; import com.yomahub.liteflow.core.NodeBooleanComponent; import org.springframework.stereotype.Component; diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/chainCache/application.properties b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/chainCache/application.properties new file mode 100644 index 000000000..2f9c44ccc --- /dev/null +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/chainCache/application.properties @@ -0,0 +1,4 @@ +liteflow.rule-source=chainCache/flow.el.xml +liteflow.chain-cache.enabled=true +liteflow.chain-cache.capacity=5 +liteflow.parse-mode=PARSE_ONE_ON_FIRST_EXEC \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/flow.el.xml b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/chainCache/flow.el.xml similarity index 100% rename from liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/flow.el.xml rename to liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/chainCache/flow.el.xml diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/application.properties b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/application.properties deleted file mode 100644 index cb4066d3c..000000000 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/resources/ruleCache/application.properties +++ /dev/null @@ -1,3 +0,0 @@ -liteflow.rule-source=ruleCache/flow.el.xml -liteflow.rule-cache.enabled=true -liteflow.rule-cache.capacity=5 \ No newline at end of file diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/chainCache/ChainCacheSpringTest.java similarity index 91% rename from liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java rename to liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/chainCache/ChainCacheSpringTest.java index 2f4b81eca..984a3e46a 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/RuleCacheSpringTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/chainCache/ChainCacheSpringTest.java @@ -1,4 +1,4 @@ -package com.yomahub.liteflow.test.ruleCache; +package com.yomahub.liteflow.test.chainCache; import cn.hutool.core.collection.CollUtil; import com.github.benmanes.caffeine.cache.Cache; @@ -9,7 +9,7 @@ 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.impl.RuleCacheLifeCycle; +import com.yomahub.liteflow.lifecycle.impl.ChainCacheLifeCycle; import com.yomahub.liteflow.test.BaseTest; import org.checkerframework.checker.nullness.qual.NonNull; import org.junit.jupiter.api.Assertions; @@ -28,12 +28,12 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; /** - * Spring环境下规则缓存测试 + * Spring环境下chain缓存测试 * @author DaleLee */ @ExtendWith(SpringExtension.class) -@ContextConfiguration("classpath:/ruleCache/application.xml") -public class RuleCacheSpringTest extends BaseTest { +@ContextConfiguration("classpath:/chainCache/application.xml") +public class ChainCacheSpringTest extends BaseTest { @Resource private FlowExecutor flowExecutor; @@ -41,14 +41,14 @@ public class RuleCacheSpringTest extends BaseTest { public void reload() { flowExecutor.reloadRule(); // 清空缓存 - Cache cache = getCache(); + Cache cache = getCache(); cache.invalidateAll(); cache.cleanUp(); } // 测试chain被淘汰 @Test - public void testRuleCache1() { + public void testChainCache1() { // 加满缓存 loadCache(); // 缓存快照 @@ -66,7 +66,7 @@ public class RuleCacheSpringTest extends BaseTest { // 测试缓存数量上限(串行) @Test - public void testRuleCache2() { + public void testChainCache2() { // 确保至少执行过5个不同的chain loadCache(); // 随机执行chain @@ -94,7 +94,7 @@ public class RuleCacheSpringTest extends BaseTest { // 测试缓存数量上限(并行) @Test - public void testRuleCache3() { + public void testChainCache3() { loadCache(); Random random = new Random(); List> futureList = CollUtil.newArrayList(); @@ -131,7 +131,7 @@ public class RuleCacheSpringTest extends BaseTest { // 测试开启规则缓存后,进入缓存的chain可以正常被更新 @Test - public void testRuleCache4() { + public void testChainCache4() { loadCache(); // 缓存快照 HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); @@ -157,7 +157,7 @@ public class RuleCacheSpringTest extends BaseTest { // 测试开启规则缓存后,进入缓存的chain被移除后无法执行 @Test - public void testRuleCache5() { + public void testChainCache5() { loadCache(); // 缓存快照 HashSet<@NonNull String> strings = CollUtil.newHashSet(getCache().asMap().keySet()); @@ -178,7 +178,7 @@ public class RuleCacheSpringTest extends BaseTest { // 测试并发下,正在执行的chain的condition被清理但仍能执行 @Test - public void testRuleCache6() throws InterruptedException { + public void testChainCache6() throws InterruptedException { // 模拟清空编译好的chain Thread thread = new Thread(()-> { Chain chain1 = FlowBus.getChain("chain1"); @@ -212,14 +212,14 @@ public class RuleCacheSpringTest extends BaseTest { Assertions.assertNull(chain.getConditionList()); } - public Cache getCache() { - return RuleCacheLifeCycle.getLifeCycle().getCache(); + public Cache getCache() { + return ChainCacheLifeCycle.getLifeCycle().getCache(); } // 获得淘汰的chain,传入淘汰前的chain集合 // 确保只有一个被淘汰时使用 String getEvictedChain(Set set) { - Cache cache = getCache(); + Cache cache = getCache(); cache.cleanUp(); Set<@NonNull String> strings = cache.asMap().keySet(); set.removeAll(strings); diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/ACmp.java similarity index 88% rename from liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java rename to liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/ACmp.java index e5999686e..d943cb205 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/ACmp.java @@ -5,7 +5,7 @@ * @email weenyc31@163.com * @Date 2020/4/1 */ -package com.yomahub.liteflow.test.ruleCache.cmp; +package com.yomahub.liteflow.test.chainCache.cmp; import com.yomahub.liteflow.core.NodeComponent; import org.springframework.stereotype.Component; diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/BCmp.java similarity index 88% rename from liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java rename to liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/BCmp.java index c79f55d47..356750126 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/BCmp.java @@ -5,7 +5,7 @@ * @email weenyc31@163.com * @Date 2020/4/1 */ -package com.yomahub.liteflow.test.ruleCache.cmp; +package com.yomahub.liteflow.test.chainCache.cmp; import com.yomahub.liteflow.core.NodeComponent; import org.springframework.stereotype.Component; diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/CCmp.java similarity index 88% rename from liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java rename to liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/CCmp.java index a5ba32f37..84dedc927 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/CCmp.java @@ -5,7 +5,7 @@ * @email weenyc31@163.com * @Date 2020/4/1 */ -package com.yomahub.liteflow.test.ruleCache.cmp; +package com.yomahub.liteflow.test.chainCache.cmp; import com.yomahub.liteflow.core.NodeComponent; import org.springframework.stereotype.Component; diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/XCmp.java similarity index 84% rename from liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java rename to liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/XCmp.java index 1c71b836c..1f671e9e4 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/XCmp.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/java/com/yomahub/liteflow/test/chainCache/cmp/XCmp.java @@ -1,4 +1,4 @@ -package com.yomahub.liteflow.test.ruleCache.cmp; +package com.yomahub.liteflow.test.chainCache.cmp; import com.yomahub.liteflow.core.NodeBooleanComponent; import org.springframework.stereotype.Component; diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/ruleCache/application.xml b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/chainCache/application.xml similarity index 78% rename from liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/ruleCache/application.xml rename to liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/chainCache/application.xml index 16170f76d..27640330e 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/ruleCache/application.xml +++ b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/chainCache/application.xml @@ -7,16 +7,17 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> - + - - - + + + + diff --git a/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/ruleCache/flow.el.xml b/liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/chainCache/flow.el.xml similarity index 100% rename from liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/ruleCache/flow.el.xml rename to liteflow-testcase-el/liteflow-testcase-el-springnative/src/test/resources/chainCache/flow.el.xml From 9cbfc965743ef320c0089556a92ff6514f16e422 Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sun, 27 Jul 2025 09:42:13 +0800 Subject: [PATCH 33/34] =?UTF-8?q?feature=20#IAY66T=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=8D=95=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/redis/application-poll-cluster-xml.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/liteflow-testcase-el/liteflow-testcase-el-redis-springboot/src/test/resources/redis/application-poll-cluster-xml.properties b/liteflow-testcase-el/liteflow-testcase-el-redis-springboot/src/test/resources/redis/application-poll-cluster-xml.properties index 6153f5d55..657442292 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-redis-springboot/src/test/resources/redis/application-poll-cluster-xml.properties +++ b/liteflow-testcase-el/liteflow-testcase-el-redis-springboot/src/test/resources/redis/application-poll-cluster-xml.properties @@ -4,6 +4,7 @@ liteflow.rule-source-ext-data={\ "pollingInterval":1,\ "pollingStartTime":2,\ "chainKey":"pollChainKey",\ - "scriptKey":"pollScriptKey"\ + "scriptKey":"pollScriptKey",\ + "scriptDataBase":1\ } liteflow.parse-mode=PARSE_ALL_ON_FIRST_EXEC \ No newline at end of file From e31d3c97d6fc4899cd3c738bf2fd578fde17edc4 Mon Sep 17 00:00:00 2001 From: DaleLee <1658850308@qq.com> Date: Sun, 27 Jul 2025 10:51:05 +0800 Subject: [PATCH 34/34] =?UTF-8?q?feature=20#IAY66T=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=8D=95=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yomahub/liteflow/test/subflow/SubflowSpringbootTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/subflow/SubflowSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/subflow/SubflowSpringbootTest.java index dcb777def..25583f539 100644 --- a/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/subflow/SubflowSpringbootTest.java +++ b/liteflow-testcase-el/liteflow-testcase-el-springboot/src/test/java/com/yomahub/liteflow/test/subflow/SubflowSpringbootTest.java @@ -36,7 +36,7 @@ public class SubflowSpringbootTest extends BaseTest { public void testSubflow1() throws Exception { LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg"); Assertions.assertTrue(response.isSuccess()); - Assertions.assertTrue(ListUtil.toList("a==>c==>d==>b","a==>c==>b==>d").contains(response.getExecuteStepStr())); + Assertions.assertTrue(ListUtil.toList("a==>c==>d==>b","a==>d==>c==>b").contains(response.getExecuteStepStr())); } //测试子chain @@ -44,7 +44,7 @@ public class SubflowSpringbootTest extends BaseTest { public void testSubflow2() throws Exception { LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg"); Assertions.assertTrue(response.isSuccess()); - Assertions.assertTrue(ListUtil.toList("a==>c==>d==>b","a==>c==>b==>d").contains(response.getExecuteStepStr())); + Assertions.assertTrue(ListUtil.toList("a==>c==>d==>b","a==>d==>c==>b").contains(response.getExecuteStepStr())); } //测试在组件里调用另一个流程