Skip to content

Commit

Permalink
Merge pull request #630 from killme2008/fix/tweak-timeout
Browse files Browse the repository at this point in the history
feat: check timeout every 3000 checkpoints, reduce the cost
  • Loading branch information
killme2008 authored Jun 8, 2024
2 parents 63db445 + 3f2ba66 commit a147bc6
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ private Map<String, Object> loadScript0(final String abPath) throws IOException
@SuppressWarnings("unchecked")
private Map<String, Object> executeModule(final Expression exp, final String abPath) {
final Env exports = new Env();
exports.configure(this, exp, -1);
exports.configure(this, exp, -1, null);
final Map<String, Object> module = exp.newEnv("exports", exports, "path", abPath);
Map<String, Object> env = exp.newEnv("__MODULE__", module, "exports", exports);
((BaseExpression) exp).execute(env, false);
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/googlecode/aviator/BaseExpression.java
Original file line number Diff line number Diff line change
Expand Up @@ -341,13 +341,13 @@ protected Env newEnv(final Map<String, Object> map, final boolean direct,
} else {
env = new Env(map);
}
env.configure(this.instance, this, getExecutionStartNs(checkExecutionTimeout));
env.configure(this.instance, this, getExecutionStartNs(checkExecutionTimeout), null);
return env;
}

protected Env genTopEnv(final Map<String, Object> map, boolean checkExecutionTimeout) {
if (map instanceof Env) {
((Env) map).configure(this.instance, this, getExecutionStartNs(checkExecutionTimeout));
((Env) map).configure(this.instance, this, getExecutionStartNs(checkExecutionTimeout), null);
}
Env env =
newEnv(map, this.instance.getOptionValue(Options.USE_USER_ENV_AS_TOP_ENV_DIRECTLY).bool,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@
import java.util.Stack;
import java.util.concurrent.atomic.AtomicLong;
import com.googlecode.aviator.AviatorEvaluatorInstance;
import com.googlecode.aviator.BaseExpression;
import com.googlecode.aviator.ClassExpression;
import com.googlecode.aviator.Expression;
import com.googlecode.aviator.Options;
Expand Down Expand Up @@ -414,6 +413,7 @@ public void onAndRight(final Token<?> lookhead) {

private void visitRightBranch(final Token<?> lookhead, final int ints,
final OperatorType opType) {
this.checkExecutionTimeout();
if (!OperationRuntime.hasRuntimeContext(this.compileEnv, opType)) {
this.mv.visitInsn(DUP);
loadEnv();
Expand Down Expand Up @@ -541,6 +541,7 @@ public void onJoinLeft(final Token<?> lookhead) {
}

private void visitLeftBranch(final Token<?> lookhead, final int ints, final OperatorType opType) {
this.checkExecutionTimeout();
if (!OperationRuntime.hasRuntimeContext(this.compileEnv, opType)) {
visitBoolean();
Label l0 = makeLabel();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

import java.util.ArrayDeque;
import java.util.List;
import java.util.concurrent.TimeUnit;
import com.googlecode.aviator.InterpretExpression;
import com.googlecode.aviator.exception.TimeoutException;
import com.googlecode.aviator.lexer.token.Token;
import com.googlecode.aviator.parser.VariableMeta;
import com.googlecode.aviator.runtime.RuntimeUtils;
Expand Down
13 changes: 9 additions & 4 deletions src/main/java/com/googlecode/aviator/runtime/RuntimeUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
*/
public final class RuntimeUtils {

private static final int CHECKPOINTS = 3000;

private RuntimeUtils() {

}
Expand Down Expand Up @@ -106,13 +108,16 @@ public static Sequence seq(final Object o, final Map<String, Object> env) {

public static void checkExecutionTimedOut(final Map<String, Object> env) {
if (env instanceof Env) {
long startNs = ((Env) env).getStartNs();
Env theEnv = (Env) env;
long startNs = theEnv.getStartNs();
if (startNs > 0) {
long execTimeoutNs = getEvalTimeoutNs(env);
if (execTimeoutNs > 0) {
if (Utils.currentTimeNanos() - startNs > execTimeoutNs) {
throw new TimeoutException("Expression execution timed out, exceeded: "
+ getInstance(env).getOptionValue(Options.EVAL_TIMEOUT_MS).number + " ms");
if (theEnv.incExecCheckpointsAndGet() % CHECKPOINTS == 0) {
if (Utils.currentTimeNanos() - startNs > execTimeoutNs) {
throw new TimeoutException("Expression execution timed out, exceeded: "
+ getInstance(env).getOptionValue(Options.EVAL_TIMEOUT_MS).number + " ms");
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,11 @@ protected Map<String, Object> newEnv(final Map<String, Object> parentEnv,
Env env = null;
if (!this.inheritEnv) {
final Env contextEnv = new Env(parentEnv, this.context);
contextEnv.configure(this.context.getInstance(), this.expression, this.context.getStartNs());
contextEnv.configure(this.context.getInstance(), this.expression, this.context.getStartNs(),
this.context.getCheckPoints());
env = new Env(contextEnv);
env.configure(this.context.getInstance(), this.expression, this.context.getStartNs());
env.configure(this.context.getInstance(), this.expression, this.context.getStartNs(),
this.context.getCheckPoints());
} else {
// assert (parentEnv == this.context);
env = (Env) parentEnv;
Expand Down
32 changes: 27 additions & 5 deletions src/main/java/com/googlecode/aviator/utils/Env.java
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,15 @@ public class Env implements Map<String, Object>, Serializable {
public static final Map<String, Object> EMPTY_ENV = Collections.emptyMap();

// The execution start timestamp in nanoseconds.
private transient long startNs = -1;
private long startNs = -1;

public static class IntCounter {
transient int n = 0;
}

// The "execution" checkpoint times
private transient IntCounter checkPoints = null;



/**
Expand Down Expand Up @@ -103,10 +111,23 @@ public void setmOverrides(final Map<String, Object> mOverrides) {
this.mOverrides = mOverrides;
}


public long getStartNs() {
return startNs;
}

public int incExecCheckpointsAndGet() {
if (this.checkPoints == null) {
checkPoints = new IntCounter();
}
return ++checkPoints.n;
}


public IntCounter getCheckPoints() {
return checkPoints;
}

public List<String> getImportedSymbols() {
return this.importedSymbols;
}
Expand Down Expand Up @@ -156,16 +177,17 @@ public void setInstance(final AviatorEvaluatorInstance instance) {
}

// Configure the env.
public void configure(final AviatorEvaluatorInstance instance, final Expression exp,
long startNs) {
public void configure(final AviatorEvaluatorInstance instance, final Expression exp, long startNs,
IntCounter checkPoints) {
this.instance = instance;
this.expression = exp;
setStartNs(startNs);
setStats(startNs, checkPoints);
}

private void setStartNs(long startNs) {
private void setStats(long startNs, IntCounter checkPoints) {
if (this.startNs == -1 && startNs > 0) {
this.startNs = startNs;
this.checkPoints = checkPoints;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
public class SimpleELPerformanceTest extends TestCase {
public void test_perf() throws Exception {

// AviatorEvaluator.setTrace(true);
// AviatorEvaluator.setOption(Options.EVAL_TIMEOUT_MS, 100);
for (int i = 0; i < 10; ++i) {
perf();
perfVarAccess();
Expand Down

0 comments on commit a147bc6

Please sign in to comment.