bug #I7EKS8 在isAccess中进行setIsEnd(true)流程没有结束的问题

bug #I7EKP3 同一个线程里分别调用2个Chain,currObj没有隔离的情况
This commit is contained in:
everywhere.z
2023-06-19 16:00:37 +08:00
parent 676a4326cd
commit 80cbd8366d
4 changed files with 84 additions and 43 deletions

View File

@@ -56,9 +56,9 @@ public class Node implements Executable, Cloneable{
private String currChainId;
private final TransmittableThreadLocal<Integer> loopIndexTL = new TransmittableThreadLocal<>();
private TransmittableThreadLocal<Integer> loopIndexTL = new TransmittableThreadLocal<>();
private final TransmittableThreadLocal<Object> currLoopObject = new TransmittableThreadLocal<>();
private TransmittableThreadLocal<Object> currLoopObject = new TransmittableThreadLocal<>();
public Node() {
@@ -77,14 +77,17 @@ public class Node implements Executable, Cloneable{
return id;
}
@Override
public void setId(String id) {
this.id = id;
}
@Override
public String getTag() {
return tag;
}
@Override
public void setTag(String tag) {
this.tag = tag;
}
@@ -141,18 +144,18 @@ public class Node implements Executable, Cloneable{
.buildNodeExecutor(instance.getNodeExecutorClass());
// 调用节点执行器进行执行
nodeExecutor.execute(instance);
// 如果组件覆盖了isEnd方法或者在在逻辑中主要调用了setEnd(true)的话,流程就会立马结束
if (instance.isEnd()) {
String errorInfo = StrUtil.format("[{}]:[{}] lead the chain to end", slot.getRequestId(),
instance.getDisplayName());
throw new ChainEndException(errorInfo);
}
}
else {
if (BooleanUtil.isTrue(liteflowConfig.getPrintExecutionLog())) {
LOG.info("[{}]:[X]skip component[{}] execution", slot.getRequestId(), instance.getDisplayName());
}
}
// 如果组件覆盖了isEnd方法或者在在逻辑中主要调用了setEnd(true)的话,流程就会立马结束
if (instance.isEnd()) {
String errorInfo = StrUtil.format("[{}]:[{}] lead the chain to end", slot.getRequestId(),
instance.getDisplayName());
throw new ChainEndException(errorInfo);
}
}
catch (ChainEndException e) {
throw e;
@@ -273,6 +276,9 @@ public class Node implements Executable, Cloneable{
}
public Node copy() throws Exception {
return (Node)this.clone();
Node node = (Node)this.clone();
node.loopIndexTL = new TransmittableThreadLocal<>();
node.currLoopObject = new TransmittableThreadLocal<>();
return node;
}
}

View File

@@ -45,22 +45,26 @@ public class ForCondition extends LoopCondition {
// 获取Break节点
Executable breakItem = this.getBreakItem();
// 循环执行
for (int i = 0; i < forCount; i++) {
executableItem.setCurrChainId(this.getCurrChainId());
// 设置循环index
setLoopIndex(executableItem, i);
executableItem.execute(slotIndex);
// 如果break组件不为空则去执行
if (ObjectUtil.isNotNull(breakItem)) {
breakItem.setCurrChainId(this.getCurrChainId());
setLoopIndex(breakItem, i);
breakItem.execute(slotIndex);
boolean isBreak = breakItem.getItemResultMetaValue(slotIndex);
if (isBreak) {
break;
try{
// 循环执行
for (int i = 0; i < forCount; i++) {
executableItem.setCurrChainId(this.getCurrChainId());
// 设置循环index
setLoopIndex(executableItem, i);
executableItem.execute(slotIndex);
// 如果break组件不为空则去执行
if (ObjectUtil.isNotNull(breakItem)) {
breakItem.setCurrChainId(this.getCurrChainId());
setLoopIndex(breakItem, i);
breakItem.execute(slotIndex);
boolean isBreak = breakItem.getItemResultMetaValue(slotIndex);
if (isBreak) {
break;
}
}
}
}finally {
removeLoopIndex(executableItem);
}
}

View File

@@ -41,29 +41,34 @@ public class IteratorCondition extends LoopCondition {
// 获取Break节点
Executable breakItem = this.getBreakItem();
int index = 0;
while (it.hasNext()) {
Object itObj = it.next();
try{
int index = 0;
while (it.hasNext()) {
Object itObj = it.next();
executableItem.setCurrChainId(this.getCurrChainId());
// 设置循环index
setLoopIndex(executableItem, index);
// 设置循环迭代器对象
setCurrLoopObject(executableItem, itObj);
// 执行可执行对象
executableItem.execute(slotIndex);
// 如果break组件不为空则去执行
if (ObjectUtil.isNotNull(breakItem)) {
breakItem.setCurrChainId(this.getCurrChainId());
setLoopIndex(breakItem, index);
setCurrLoopObject(breakItem, itObj);
breakItem.execute(slotIndex);
boolean isBreak = breakItem.getItemResultMetaValue(slotIndex);
if (isBreak) {
break;
executableItem.setCurrChainId(this.getCurrChainId());
// 设置循环index
setLoopIndex(executableItem, index);
// 设置循环迭代器对象
setCurrLoopObject(executableItem, itObj);
// 执行可执行对象
executableItem.execute(slotIndex);
// 如果break组件不为空则去执行
if (ObjectUtil.isNotNull(breakItem)) {
breakItem.setCurrChainId(this.getCurrChainId());
setLoopIndex(breakItem, index);
setCurrLoopObject(breakItem, itObj);
breakItem.execute(slotIndex);
boolean isBreak = breakItem.getItemResultMetaValue(slotIndex);
if (isBreak) {
break;
}
}
index++;
}
index++;
}finally{
removeLoopIndex(executableItem);
removeCurrLoopObject(executableItem);
}
}

View File

@@ -55,4 +55,30 @@ public abstract class LoopCondition extends Condition {
}
}
protected void removeLoopIndex(Executable executableItem){
if (executableItem instanceof Chain) {
((Chain) executableItem).getConditionList().forEach(this::removeLoopIndex);
}
else if (executableItem instanceof Condition) {
((Condition) executableItem).getExecutableGroup()
.forEach((key, value) -> value.forEach(this::removeLoopIndex));
}
else if (executableItem instanceof Node) {
((Node) executableItem).removeLoopIndex();
}
}
protected void removeCurrLoopObject(Executable executableItem){
if (executableItem instanceof Chain) {
((Chain) executableItem).getConditionList().forEach(this::removeCurrLoopObject);
}
else if (executableItem instanceof Condition) {
((Condition) executableItem).getExecutableGroup()
.forEach((key, value) -> value.forEach(this::removeCurrLoopObject));
}
else if (executableItem instanceof Node) {
((Node) executableItem).removeCurrLoopObject();
}
}
}