!266 [ISSUE #I8MW6Q] 提供节点和脚本的卸载功能

Merge pull request !266 from DaleLee/issue/#I8MW6Q-2
This commit is contained in:
铂赛东
2024-02-17 07:51:02 +00:00
committed by Gitee
48 changed files with 1930 additions and 6 deletions

View File

@@ -37,6 +37,7 @@ import com.yomahub.liteflow.spi.holder.ContextAwareHolder;
import com.yomahub.liteflow.spi.holder.DeclComponentParserHolder;
import com.yomahub.liteflow.util.CopyOnWriteHashMap;
import com.yomahub.liteflow.core.proxy.LiteFlowProxyUtil;
import com.yomahub.liteflow.util.NodeScanner;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -241,6 +242,12 @@ public class FlowBus {
return nodeMap.get(nodeId);
}
// 获取某一个 chainId 下的所有 nodeId
public static List<Node> getNodesByChainId(String chainId) {
Chain chain = getChain(chainId);
return NodeScanner.getNodesInChain(chain);
}
public static Map<String, Node> getNodeMap() {
return nodeMap;
}
@@ -297,6 +304,11 @@ public class FlowBus {
Arrays.stream(chainIds).forEach(FlowBus::removeChain);
}
// 移除节点
public static boolean removeNode(String nodeId) {
return nodeMap.remove(nodeId) != null;
}
// 判断是否是降级组件,如果是则添加到 fallbackNodeMap
private static void addFallbackNode(Node node) {
NodeComponent nodeComponent = node.getInstance();
@@ -309,6 +321,33 @@ public class FlowBus {
fallbackNodeMap.put(nodeType, node);
}
// 重新加载脚本
public static void reloadScript(String nodeId, String script) {
Node node = getNode(nodeId);
if (node == null || !node.getType().isScript()) {
return;
}
// 更新脚本
node.setScript(script);
ScriptExecutorFactory.loadInstance()
.getScriptExecutor(node.getLanguage())
.load(nodeId, script);
}
// 卸载脚本节点
public static boolean unloadScriptNode(String nodeId) {
Node node = getNode(nodeId);
if (node == null || !node.getType().isScript()) {
return false;
}
// 卸载脚本
ScriptExecutorFactory.loadInstance()
.getScriptExecutor(node.getLanguage())
.unLoad(nodeId);
// 移除脚本
return removeNode(nodeId);
}
public static void clearStat(){
initStat.set(false);
}

View File

@@ -2,15 +2,12 @@ package com.yomahub.liteflow.script;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.annotation.util.AnnoUtil;
import com.yomahub.liteflow.context.ContextBean;
import com.yomahub.liteflow.enums.ScriptTypeEnum;
import com.yomahub.liteflow.exception.LiteFlowException;
import com.yomahub.liteflow.slot.DataBus;
import com.yomahub.liteflow.slot.Slot;
import javax.script.ScriptException;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
@@ -28,6 +25,12 @@ public abstract class ScriptExecutor {
public abstract void load(String nodeId, String script);
// 卸载脚本(不包含 node
public abstract void unLoad(String nodeId);
// 获取该执行器下的所有 nodeId
public abstract List<String> getNodeIds();
public Object execute(ScriptExecuteWrap wrap) throws Exception{
try {
return executeScript(wrap);

View File

@@ -7,7 +7,16 @@ import com.yomahub.liteflow.script.ScriptExecuteWrap;
import com.yomahub.liteflow.script.ScriptExecutor;
import com.yomahub.liteflow.script.exception.ScriptLoadException;
import com.yomahub.liteflow.util.CopyOnWriteHashMap;
import javax.script.*;
import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.SimpleBindings;
import javax.script.ScriptException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
@@ -44,7 +53,16 @@ public abstract class JSR223ScriptExecutor extends ScriptExecutor {
String errorMsg = StrUtil.format("script loading error for node[{}], error msg:{}", nodeId, e.getMessage());
throw new ScriptLoadException(errorMsg);
}
}
@Override
public void unLoad(String nodeId) {
compiledScriptMap.remove(nodeId);
}
@Override
public List<String> getNodeIds() {
return new ArrayList<>(compiledScriptMap.keySet());
}
@Override

View File

@@ -0,0 +1,69 @@
package com.yomahub.liteflow.util;
import com.yomahub.liteflow.flow.element.Chain;
import com.yomahub.liteflow.flow.element.Condition;
import com.yomahub.liteflow.flow.element.Executable;
import com.yomahub.liteflow.flow.element.Node;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
/**
* 节点扫描器
*
* @author DaleLee
* @since 2.12.0
*/
public class NodeScanner {
/**
* 获取 Chain 中的所有 Node
*
* @param chain Chain
* @return Node 集合
*/
public static List<Node> getNodesInChain(Chain chain) {
List<Node> result = new ArrayList<>();
if (chain == null) {
return result;
}
for (Condition condition : chain.getConditionList()) {
result.addAll(getNodesInCondition(condition));
}
return result;
}
/**
* 获取 Condition 中的所有 Node
*
* @param condition Condition
* @return Node 集合
*/
public static List<Node> getNodesInCondition(Condition condition) {
List<Node> result = new ArrayList<>();
if (condition == null) {
return result;
}
// 层序遍历
Queue<Executable> queue = new LinkedList<>();
queue.offer(condition);
while (!queue.isEmpty()) {
Executable cur = queue.poll();
if (cur instanceof Condition) {
Map<String, List<Executable>> executableGroup = ((Condition) cur).getExecutableGroup();
for (List<Executable> executables : executableGroup.values()) {
executables.forEach(queue::offer);
}
} else if (cur instanceof Node) {
result.add((Node) cur);
}
}
return result;
}
}