diff --git a/liteflow-core/pom.xml b/liteflow-core/pom.xml
index c93d6578d6225604eaaac6f6e5351be82d040fef..635f5925722c44965a344ecfafe12a8398b5d980 100644
--- a/liteflow-core/pom.xml
+++ b/liteflow-core/pom.xml
@@ -54,5 +54,9 @@
commons-io
commons-io
+
+ com.github.ben-manes.caffeine
+ caffeine
+
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 50118790e1b3551fcbadd6e400328c52bf5edb28..58c18df1a6f54782faba56b80c17d2886beadc1e 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.RuleCachePostProcessFlowExecuteLifeCycle;
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,11 @@ public class FlowExecutor {
IdGeneratorHolder.init();
}
+ // 规则缓存
+ if (isStart && liteflowConfig.isRuleCacheEnabled()) {
+ LifeCycleHolder.addLifeCycle(new RuleCachePostProcessFlowExecuteLifeCycle());
+ }
+
String ruleSource = liteflowConfig.getRuleSource();
if (StrUtil.isBlank(ruleSource)) {
// 查看有没有Parser的SPI实现
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/FlowBus.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/FlowBus.java
index 1294248a0cfc38e43d7931fd81a1201519892b85..340baeea713b4d5a5f5cdc52544682ab226b74e0 100644
--- a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/FlowBus.java
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/FlowBus.java
@@ -10,6 +10,7 @@ package com.yomahub.liteflow.flow;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.annotation.FallbackCmp;
import com.yomahub.liteflow.annotation.util.AnnoUtil;
@@ -22,6 +23,8 @@ import com.yomahub.liteflow.enums.FlowParserTypeEnum;
import com.yomahub.liteflow.enums.NodeTypeEnum;
import com.yomahub.liteflow.exception.ComponentCannotRegisterException;
import com.yomahub.liteflow.exception.NullNodeTypeException;
+import com.yomahub.liteflow.flow.cache.CacheFactory;
+import com.yomahub.liteflow.flow.cache.ChainRepository;
import com.yomahub.liteflow.flow.element.Chain;
import com.yomahub.liteflow.flow.element.Condition;
import com.yomahub.liteflow.flow.element.Node;
@@ -68,15 +71,22 @@ public class FlowBus {
static {
LiteflowConfig liteflowConfig = LiteflowConfigGetter.get();
+ Map expectedChainMap;
if (liteflowConfig.getFastLoad()){
- chainMap = new HashMap<>();
+ expectedChainMap = new HashMap<>();
nodeMap = new HashMap<>();
fallbackNodeMap = new HashMap<>();
}else{
- chainMap = new CopyOnWriteHashMap<>();
+ expectedChainMap = new CopyOnWriteHashMap<>();
nodeMap = new CopyOnWriteHashMap<>();
fallbackNodeMap = new CopyOnWriteHashMap<>();
}
+ // 开启了规则缓存
+ if (liteflowConfig.isRuleCacheEnabled()) {
+ Integer capacity = liteflowConfig.getRuleCacheCapacity();
+ expectedChainMap = CacheFactory.newCache(capacity);
+ }
+ chainMap = expectedChainMap;
}
public static Chain getChain(String id) {
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/CacheFactory.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/CacheFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..2cf8e3494eaf526509b4e3c566933fe6ab1f7e69
--- /dev/null
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/CacheFactory.java
@@ -0,0 +1,27 @@
+package com.yomahub.liteflow.flow.cache;
+
+import com.github.benmanes.caffeine.cache.Cache;
+import com.github.benmanes.caffeine.cache.Caffeine;
+
+import java.util.Map;
+
+/**
+ * 缓存工厂
+ * @author DaleLee
+ * @since
+ */
+public class CacheFactory {
+ /**
+ * 构建一个缓存
+ * @param capacity 缓存容量
+ * @return Map形式的缓存
+ * @param 键
+ * @param 值
+ */
+ public static Map newCache(int capacity) {
+ Cache cache = Caffeine.newBuilder()
+ .maximumSize(capacity)
+ .build();
+ return cache.asMap();
+ }
+}
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/ChainFinder.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/ChainFinder.java
new file mode 100644
index 0000000000000000000000000000000000000000..425feaf8682520e8dd1bc1b3365a9a8747292440
--- /dev/null
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/ChainFinder.java
@@ -0,0 +1,15 @@
+package com.yomahub.liteflow.flow.cache;
+
+/**
+ * Chain查找器
+ * @author DaleLee
+ * @since
+ */
+public interface ChainFinder {
+ /**
+ * 根据chainId查找对应的RawChain
+ * @param chainId chainId
+ * @return RawChain
+ */
+ RawChain findChainById(String chainId);
+}
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/ChainRepository.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/ChainRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..b5624c58a0031aa9e0c360280d720a9043045646
--- /dev/null
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/ChainRepository.java
@@ -0,0 +1,49 @@
+package com.yomahub.liteflow.flow.cache;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 外部数据源下Chain的统一访问类
+ * @author DaleLee
+ * @since
+ */
+public class ChainRepository {
+ private static final List chainFinders = new ArrayList<>();
+
+ /**
+ * 根据chainId获取对应的RawChain
+ * @param chainId chainId
+ * @return RawChain
+ */
+ public static RawChain getChain(String chainId) {
+ if (CollUtil.isEmpty(chainFinders)) {
+ return null;
+ }
+ for (ChainFinder chainFinder : chainFinders) {
+ RawChain rawChain = chainFinder.findChainById(chainId);
+ if (ObjectUtil.isNotNull(rawChain)) {
+ return rawChain;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 添加一个ChainFinder
+ * @param chainFinder ChainFinder
+ */
+ public static void addFinder(ChainFinder chainFinder) {
+ chainFinders.add(chainFinder);
+ }
+
+ /**
+ * 清空所有的ChainFinder
+ */
+ public static void clearFinders() {
+ chainFinders.clear();
+ }
+}
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RawChain.java b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RawChain.java
new file mode 100644
index 0000000000000000000000000000000000000000..61079e72ba703f7ef671bffbe90c84fe30ca2866
--- /dev/null
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RawChain.java
@@ -0,0 +1,57 @@
+package com.yomahub.liteflow.flow.cache;
+
+/**
+ * Chain的原始信息
+ * @author DaleLee
+ * @since
+ */
+public class RawChain {
+ /**
+ * id
+ */
+ private String chainId;
+ /**
+ * EL表达式
+ */
+ private String el;
+ /**
+ * 路由
+ */
+ private String route;
+ /**
+ * 命名空间
+ */
+ private String namespace;
+
+ public String getChainId() {
+ return chainId;
+ }
+
+ public void setChainId(String chainId) {
+ this.chainId = chainId;
+ }
+
+ public String getEl() {
+ return el;
+ }
+
+ public void setEl(String el) {
+ this.el = el;
+ }
+
+ public String getRoute() {
+ return route;
+ }
+
+ public void setRoute(String route) {
+ this.route = route;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public void setNamespace(String namespace) {
+ this.namespace = namespace;
+ }
+}
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 0000000000000000000000000000000000000000..ba1a249f05e0c42865fd9a44e2ab3721b18373b5
--- /dev/null
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/flow/cache/RuleCachePostProcessFlowExecuteLifeCycle.java
@@ -0,0 +1,45 @@
+package com.yomahub.liteflow.flow.cache;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.yomahub.liteflow.builder.el.LiteFlowChainELBuilder;
+import com.yomahub.liteflow.flow.FlowBus;
+import com.yomahub.liteflow.lifecycle.PostProcessFlowExecuteLifeCycle;
+import com.yomahub.liteflow.slot.Slot;
+
+/**
+ * Chain执行前的缓存处理
+ * @author DaleLee
+ * @since
+ */
+public class RuleCachePostProcessFlowExecuteLifeCycle implements PostProcessFlowExecuteLifeCycle {
+ @Override
+ public void postProcessBeforeFlowExecute(String chainId, Slot slot) {
+ if (!FlowBus.containChain(chainId)) {
+ // 如果chain不存在,尝试去加载
+ tryLoadChain(chainId);
+ }
+ }
+
+ @Override
+ public void postProcessAfterFlowExecute(String chainId, Slot slot) {
+
+ }
+
+ /**
+ * 尝试加载chain
+ * @param chainId chainId
+ */
+ private void tryLoadChain(String chainId) {
+ RawChain rawChain = ChainRepository.getChain(chainId);
+ if (ObjectUtil.isNull(rawChain)) {
+ return;
+ }
+ LiteFlowChainELBuilder
+ .createChain()
+ .setChainId(chainId)
+ .setEL(rawChain.getEl())
+ .setNamespace(rawChain.getNamespace())
+ .setRoute(rawChain.getRoute())
+ .build();
+ }
+}
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 d269da250cc645584451d281ba47818cf425522b..4b4db3f97a67dbb81eb5b5491faa9dce7b90c23d 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
@@ -124,6 +124,9 @@ public class LiteflowConfig {
//脚本特殊设置选项
private Map scriptSetting;
+ // 规则缓存容量
+ private Integer ruleCacheCapacity;
+
public Boolean getEnableMonitorFile() {
return enableMonitorFile;
}
@@ -509,4 +512,16 @@ public class LiteflowConfig {
public void setScriptSetting(Map scriptSetting) {
this.scriptSetting = scriptSetting;
}
+
+ 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-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/SQLXmlELParser.java b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/SQLXmlELParser.java
index a758fd6069ed8e1fdb5ec8291e28ef4706ee37e8..4b8c884432ad61c080199dad9089d2f00879a3d7 100644
--- a/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/SQLXmlELParser.java
+++ b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/SQLXmlELParser.java
@@ -6,11 +6,14 @@ import cn.hutool.core.map.MapUtil;
import cn.hutool.core.text.StrFormatter;
import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.core.FlowInitHook;
+import com.yomahub.liteflow.flow.cache.ChainRepository;
import com.yomahub.liteflow.parser.constant.ReadType;
import com.yomahub.liteflow.parser.el.ClassXmlFlowELParser;
import com.yomahub.liteflow.parser.sql.exception.ELSQLException;
+import com.yomahub.liteflow.parser.sql.finder.SQLChainFinder;
import com.yomahub.liteflow.parser.sql.read.SqlReadFactory;
import com.yomahub.liteflow.parser.sql.util.JDBCHelper;
+import com.yomahub.liteflow.parser.sql.util.SQLUtil;
import com.yomahub.liteflow.parser.sql.vo.SQLParserVO;
import com.yomahub.liteflow.property.LiteflowConfig;
import com.yomahub.liteflow.property.LiteflowConfigGetter;
@@ -49,6 +52,18 @@ public class SQLXmlELParser extends ClassXmlFlowELParser {
throw new ELSQLException(ERROR_COMMON_MSG);
}
+ if (liteflowConfig.isRuleCacheEnabled()) {
+ // 启用规则缓存则禁用轮询
+ sqlParserVO.setPollingEnabled(false);
+ // 如果用户设置了自定义SQL,则初次查询的chain数据由用户决定
+ // 否则限制初次查询返回的chain的数量
+ if (StrUtil.isBlank(sqlParserVO.getChainCustomSql())) {
+ String querySql = SQLUtil.buildLimitChainsQuerySql(sqlParserVO, liteflowConfig.getRuleCacheCapacity());
+ sqlParserVO.setChainCustomSql(querySql);
+ }
+ ChainRepository.addFinder(new SQLChainFinder());
+ }
+
// 检查配置文件
checkParserVO(sqlParserVO);
diff --git a/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/finder/SQLChainFinder.java b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/finder/SQLChainFinder.java
new file mode 100644
index 0000000000000000000000000000000000000000..d1713661d73b98dc55999ae05cec4fa78b20d4aa
--- /dev/null
+++ b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/finder/SQLChainFinder.java
@@ -0,0 +1,54 @@
+package com.yomahub.liteflow.parser.sql.finder;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.yomahub.liteflow.exception.ChainDuplicateException;
+import com.yomahub.liteflow.flow.cache.ChainFinder;
+import com.yomahub.liteflow.flow.cache.RawChain;
+import com.yomahub.liteflow.parser.constant.ReadType;
+import com.yomahub.liteflow.parser.sql.read.SqlRead;
+import com.yomahub.liteflow.parser.sql.read.SqlReadFactory;
+import com.yomahub.liteflow.parser.sql.read.impl.ChainRead;
+import com.yomahub.liteflow.parser.sql.read.vo.ChainVO;
+import com.yomahub.liteflow.parser.sql.util.SQLUtil;
+import com.yomahub.liteflow.parser.sql.vo.SQLParserVO;
+
+import java.util.List;
+
+/**
+ * SQL数据源的ChainFinder实现
+ * @author DaleLee
+ * @since
+ */
+public class SQLChainFinder implements ChainFinder {
+
+ @Override
+ public RawChain findChainById(String chainId) {
+ SqlRead sqlRead = SqlReadFactory.getSqlRead(ReadType.CHAIN);
+ ChainRead chainRead = (ChainRead) sqlRead;
+ SQLParserVO config = chainRead.config;
+ // 构建chain查询sql
+ String sql = SQLUtil.buildChainQuerySQL(config, chainId);
+ List chainVOList = chainRead.read(sql);
+ if (CollUtil.isEmpty(chainVOList)) {
+ return null;
+ }
+ if (chainVOList.size() > 1) {
+ throw new ChainDuplicateException("SQL data source chain duplicate, chainName: " + chainId);
+ }
+ ChainVO chainVO = chainVOList.get(0);
+ return covert2RawChain(chainVO);
+ }
+
+ private RawChain covert2RawChain(ChainVO chainVO) {
+ if (chainVO == null) {
+ return null;
+ }
+ RawChain rawChain = new RawChain();
+ rawChain.setChainId(chainVO.getChainId());
+ rawChain.setEl(chainVO.getBody());
+ rawChain.setNamespace(chainVO.getNamespace());
+ rawChain.setRoute(chainVO.getRoute());
+ return rawChain;
+ }
+}
diff --git a/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/read/AbstractSqlRead.java b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/read/AbstractSqlRead.java
index 01cb01148e0182a7a1092221f954827ca6644496..56e5267aaf093323bdfa89a1618dd4f02633e288 100644
--- a/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/read/AbstractSqlRead.java
+++ b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/read/AbstractSqlRead.java
@@ -41,6 +41,11 @@ public abstract class AbstractSqlRead implements SqlRead {
// 如果允许,就打印 sql 语句
logSqlIfEnable(sqlCmd);
+ return read(sqlCmd);
+ }
+
+ @Override
+ public List read(String sqlCmd) {
List result = new ArrayList<>();
Connection conn = null;
PreparedStatement stmt = null;
diff --git a/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/read/SqlRead.java b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/read/SqlRead.java
index b56b31a30c6edc3a286b794fab418640265f9419..d18e1736492a93b5005d1ff1565c62d8164a8deb 100644
--- a/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/read/SqlRead.java
+++ b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/read/SqlRead.java
@@ -9,6 +9,7 @@ import java.util.List;
*
* @author tangkc
* @author houxinyu
+ * @author DaleLee
* @since 2.11.1
*/
public interface SqlRead {
@@ -20,6 +21,14 @@ public interface SqlRead {
*/
List read();
+ /**
+ * 通过指定SQL读取
+ *
+ * @param sqlCmd SQL命令
+ * @return 返回读取到的数据
+ */
+ List read(String sqlCmd);
+
/**
* 类型
*
diff --git a/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/util/SQLUtil.java b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/util/SQLUtil.java
new file mode 100644
index 0000000000000000000000000000000000000000..b4becdd122aeee033cf280d89b26e3192c65b398
--- /dev/null
+++ b/liteflow-rule-plugin/liteflow-rule-sql/src/main/java/com/yomahub/liteflow/parser/sql/util/SQLUtil.java
@@ -0,0 +1,42 @@
+package com.yomahub.liteflow.parser.sql.util;
+
+import cn.hutool.core.util.StrUtil;
+import com.yomahub.liteflow.parser.sql.vo.SQLParserVO;
+
+/**
+ * SQL构建工具类
+ */
+public class SQLUtil {
+
+ private static final String SQL_PATTERN = "SELECT * FROM {} WHERE {}='{}' AND {}='{}'";
+
+ private static final String SQL_PATTERN_WITH_LIMIT = "SELECT * FROM {} WHERE {}='{}' LIMIT {}";
+
+ /**
+ * 构建查询指定条数chain的SQL
+ * @param config SQL配置
+ * @param limit 上限
+ * @return SQL
+ */
+ public static String buildLimitChainsQuerySql(SQLParserVO config, Integer limit) {
+ String chainTableName = config.getChainTableName();
+ String chainApplicationNameField = config.getChainApplicationNameField();
+ String applicationName = config.getApplicationName();
+ return StrUtil.format(SQL_PATTERN_WITH_LIMIT, chainTableName, chainApplicationNameField, applicationName, limit);
+ }
+
+ /**
+ * 构建查询某一个chain的SQL
+ * @param config SQL配置
+ * @param chainId chainId
+ * @return SQL
+ */
+ public static String buildChainQuerySQL(SQLParserVO config, String chainId) {
+ String chainTableName = config.getChainTableName();
+ String chainApplicationNameField = config.getChainApplicationNameField();
+ String applicationName = config.getApplicationName();
+ String chainNameField = config.getChainNameField();
+ return StrUtil.format(SQL_PATTERN, chainTableName, chainApplicationNameField, applicationName,
+ chainNameField, chainId);
+ }
+}
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 930a62d4c919f4751e09790e3473f5a9a932ae50..0e37d6495c662442ed4173702d70a0190a2a9970 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
@@ -101,6 +101,9 @@ public class LiteflowProperty {
//脚本特殊设置选项
private Map scriptSetting;
+ // 规则缓存容量
+ private Integer ruleCacheCapacity;
+
public boolean isEnableMonitorFile() {
return enableMonitorFile;
}
@@ -336,4 +339,12 @@ public class LiteflowProperty {
public void setScriptSetting(Map scriptSetting) {
this.scriptSetting = scriptSetting;
}
+
+ 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 37356fcb3a9c0db16f3061022781b13680d2a8d7..f3fd544866c6144324677f8f88dc4437fa3bbd91 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
@@ -54,6 +54,7 @@ public class LiteflowPropertyAutoConfiguration {
liteflowConfig.setDelay(liteflowMonitorProperty.getDelay());
liteflowConfig.setPeriod(liteflowMonitorProperty.getPeriod());
liteflowConfig.setScriptSetting(property.getScriptSetting());
+ liteflowConfig.setRuleCacheCapacity(property.getRuleCacheCapacity());
return liteflowConfig;
}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/SQLWithXmlELRuleCacheSpringbootTest.java b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/SQLWithXmlELRuleCacheSpringbootTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..37345c445fbbd7de71253aec24ec7dbe8662e548
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/SQLWithXmlELRuleCacheSpringbootTest.java
@@ -0,0 +1,56 @@
+package com.yomahub.liteflow.test.ruleCache;
+
+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.test.BaseTest;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+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 org.springframework.test.context.junit.jupiter.SpringExtension;
+
+import javax.annotation.Resource;
+
+/**
+ * SQL数据源规则缓存测试
+ * @author DaleLee
+ * @since
+ */
+@ExtendWith(SpringExtension.class)
+@TestPropertySource(value = "classpath:/application-rule-cache.properties")
+@SpringBootTest(classes = SQLWithXmlELRuleCacheSpringbootTest.class)
+@EnableAutoConfiguration
+@ComponentScan({ "com.yomahub.liteflow.test.ruleCache.cmp" })
+public class SQLWithXmlELRuleCacheSpringbootTest extends BaseTest {
+ @Resource
+ private FlowExecutor flowExecutor;
+
+ @Test
+ public void testRuleCache() throws Exception{
+ // 缓存大小为3
+ Assertions.assertEquals(3, FlowBus.getChainMap().size());
+ // 缓存命中的情况
+ Assertions.assertTrue(FlowBus.containChain("chain1"));
+ LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
+ Assertions.assertTrue(response.isSuccess());
+ Assertions.assertEquals("a==>b==>c", response.getExecuteStepStr());
+
+ // 缓存未命中,但加载成功
+ Assertions.assertFalse(FlowBus.containChain(""));
+ response = flowExecutor.execute2Resp("", "arg");
+ Assertions.assertEquals("x0[if 脚本]==>a==>b", response.getExecuteStepStr());
+ // 已加载
+ Assertions.assertTrue(FlowBus.containChain(""));
+
+ // 缓存未命中,且加载失败
+ Assertions.assertFalse(FlowBus.containChain("chain5"));
+ response = flowExecutor.execute2Resp("chain5", "arg");
+ Assertions.assertFalse(response.isSuccess());
+ Assertions.assertEquals(ChainNotFoundException.class, response.getSlot().getException().getClass());
+ }
+}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.java
new file mode 100644
index 0000000000000000000000000000000000000000..20d073b52e0017cb21d8005c168f4c0b71ca8341
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/ACmp.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("a")
+public class ACmp extends NodeComponent {
+
+ @Override
+ public void process() {
+ System.out.println("ACmp executed!");
+ }
+
+}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/BCmp.java
new file mode 100644
index 0000000000000000000000000000000000000000..c79f55d47dbb1fa1e9bf2af41ee4658e67487173
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-sql-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-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.java
new file mode 100644
index 0000000000000000000000000000000000000000..adcf920f6723379c4eb1c7f2438cb1d710246b50
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/ruleCache/cmp/CCmp.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("c")
+public class CCmp extends NodeComponent {
+
+ @Override
+ public void process() {
+ System.out.println("CCmp executed!");
+ }
+
+}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/sql/cmp/X0Cmp.java b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/sql/cmp/X0Cmp.java
new file mode 100644
index 0000000000000000000000000000000000000000..f7133f2bffb22cf6afb63a05465764b3fae493ba
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/java/com/yomahub/liteflow/test/sql/cmp/X0Cmp.java
@@ -0,0 +1,5 @@
+package com.yomahub.liteflow.test.sql.cmp;
+
+
+public class X0Cmp {
+}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/resources/application-rule-cache.properties b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/resources/application-rule-cache.properties
new file mode 100644
index 0000000000000000000000000000000000000000..a97a0a1aa25baa253d7060de55cb58d3c68b3ec3
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-sql-springboot/src/test/resources/application-rule-cache.properties
@@ -0,0 +1,26 @@
+liteflow.rule-source-ext-data={\
+ "url":"jdbc:h2:mem:test_db;MODE=MySQL",\
+ "driverClassName":"org.h2.Driver",\
+ "username":"root",\
+ "password":"123456",\
+ "applicationName":"demo",\
+ "chainTableName":"EL_TABLE",\
+ "chainApplicationNameField":"application_name",\
+ "chainNameField":"chain_name",\
+ "elDataField":"EL_DATA",\
+ "scriptTableName":"script_node_table",\
+ "scriptApplicationNameField":"application_name",\
+ "scriptIdField":"script_node_id",\
+ "scriptNameField":"script_node_name",\
+ "scriptDataField":"script_node_data",\
+ "scriptLanguageField":"script_language",\
+ "scriptTypeField":"script_node_type"\
+ }
+liteflow.rule-cache-capacity=3
+spring.datasource.driver-class-name=org.h2.Driver
+spring.datasource.url=jdbc:h2:mem:test_db;MODE=MySQL
+spring.datasource.username=root
+spring.datasource.password=123456
+spring.datasource.schema=classpath:/sql/schema.sql
+spring.datasource.data=classpath:/sql/data.sql
+spring.datasource.platform=h2
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 00b1a19986dc5e63190b34ddb11f12e93b4de5a2..9970b5991f95f346fd5d50c963227dec6fdafea5 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}
+