Skip to content

Commit

Permalink
support thread reentrant execute
Browse files Browse the repository at this point in the history
  • Loading branch information
DQinYuan authored and baoxingjie committed Oct 15, 2021
1 parent 510745c commit e3a24c5
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 2 deletions.
25 changes: 23 additions & 2 deletions src/main/java/com/ql/util/express/ExpressRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ public class ExpressRunner {
*/
ExpressPackage rootExpressPackage = new ExpressPackage(null);

/**
* 线程冲入次数
*/
private final ThreadLocal<Integer> threadReentrantCount = ThreadLocal.withInitial(() -> 0);

public AppendingClassMethodManager getAppendingClassMethodManager() {
return appendingClassMethodManager;
}
Expand Down Expand Up @@ -613,8 +618,24 @@ public Object execute(String expressString, IExpressContext<String,Object> conte
} else {
parseResult = this.parseInstructionSet(expressString);
}
return InstructionSetRunner.executeOuter(this,parseResult,this.loader,context, errorList,
isTrace,false,aLog,false);
return executeReentrant(parseResult, context, errorList, isTrace, aLog);
}

private Object executeReentrant(InstructionSet sets, IExpressContext<String,Object> aContext,
List<String> errorList, boolean isTrace, Log aLog) throws Exception {
try {
int reentrantCount = threadReentrantCount.get() + 1;
threadReentrantCount.set(reentrantCount);

return reentrantCount > 1?
// 线程重入
InstructionSetRunner.execute(this, sets, this.loader, aContext, errorList,
isTrace, false, true, aLog, false):
InstructionSetRunner.executeOuter(this, sets, this.loader, aContext, errorList,
isTrace,false,aLog,false);
} finally {
threadReentrantCount.set(threadReentrantCount.get() - 1);
}
}

public RuleResult executeRule(String expressString, IExpressContext<String,Object> context, boolean isCache, boolean isTrace)
Expand Down
40 changes: 40 additions & 0 deletions src/test/java/com/ql/util/express/bugfix/ExecuteReentrantTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.ql.util.express.bugfix;

import com.ql.util.express.ArraySwap;
import com.ql.util.express.DefaultContext;
import com.ql.util.express.ExpressRunner;
import com.ql.util.express.InstructionSetContext;
import com.ql.util.express.OperateData;
import com.ql.util.express.instruction.op.OperatorBase;
import org.junit.Assert;
import org.junit.Test;

/**
* 线程可重入执行测试
*/
public class ExecuteReentrantTest {

@Test
public void executeReentrantTest() throws Exception {
String express = "eval('eval(\\'1+1\\')')";
ExpressRunner runner = new ExpressRunner(false, true);
runner.addFunction("eval", new OperatorBase() {
@Override
public OperateData executeInner(InstructionSetContext parent, ArraySwap list) throws Exception {
Object res = runner.execute(list.get(0).toString(), parent, null,
false, true);
return new OperateData(res, res.getClass());
}
});

Object res = runner.execute(express, new DefaultContext<>(), null,
false, true);
Assert.assertEquals(2, res);

Object res1 = runner.execute("m = 'aaa';" +
"eval('m')", new DefaultContext<>(), null,
false, true);
Assert.assertEquals("aaa", res1);
}

}

0 comments on commit e3a24c5

Please sign in to comment.