Skip to content

Commit 86f432b

Browse files
committed
re-worked approach to #1558
no more locking at all except for the callonce / callSingle flows if any troublesome value is encountered we throw it out with a log message and the name of the variable if tests depend on functions from callonce / callSingle or java classes / code they may fail but thats the fault of the user - the log messages should guide you what to stop doing and if you switch on TRACE logging you will see more detailed stack traces for diagnosis
1 parent e7b3888 commit 86f432b

File tree

2 files changed

+37
-55
lines changed

2 files changed

+37
-55
lines changed

karate-core/src/main/java/com/intuit/karate/core/ScenarioEngine.java

+34-54
Original file line numberDiff line numberDiff line change
@@ -1022,7 +1022,7 @@ public void init() { // not in constructor because it has to be on Runnable.run(
10221022
runtime.magicVariables.forEach((k, v) -> {
10231023
// even hidden variables may need pre-processing
10241024
// for e.g. the __arg may contain functions that originated in a different js context
1025-
recurseAndAttach(v, seen);
1025+
recurseAndAttach(k, v, seen);
10261026
setHiddenVariable(k, v);
10271027
});
10281028
attachVariables(seen); // re-hydrate any functions from caller or background
@@ -1048,76 +1048,51 @@ public void init() { // not in constructor because it has to be on Runnable.run(
10481048

10491049
private void attachVariables(Set<Object> seen) {
10501050
vars.forEach((k, v) -> {
1051-
switch (v.type) {
1052-
case JS_FUNCTION:
1053-
Value value = attach(v.getValue());
1054-
v = new Variable(value);
1055-
vars.put(k, v);
1056-
break;
1057-
case MAP:
1058-
case LIST:
1059-
recurseAndAttach(v.getValue(), seen);
1060-
break;
1061-
case OTHER:
1062-
if (v.isJsFunctionWrapper()) {
1063-
JsFunction jf = v.getValue();
1064-
Value attached = attachSource(jf.source);
1065-
v = new Variable(attached);
1066-
vars.put(k, v);
1067-
}
1068-
break;
1069-
default:
1070-
// do nothing
1051+
Object o = recurseAndAttach(k, v.getValue(), seen);
1052+
if (o == null) {
1053+
o = v.getValue();
1054+
} else {
1055+
try {
1056+
vars.put(k, new Variable(o));
1057+
} catch (Exception e) {
1058+
logger.debug("[*** attach variables ***] failed to attach graal value: {} - {}", k, e.getMessage());
1059+
}
10711060
}
1072-
JS.put(k, v.getValue());
1061+
JS.put(k, o);
10731062
});
10741063
}
10751064

10761065
protected Map<String, Variable> detachVariables() {
10771066
Set<Object> seen = Collections.newSetFromMap(new IdentityHashMap());
10781067
Map<String, Variable> detached = new HashMap(vars.size());
10791068
vars.forEach((k, v) -> {
1080-
switch (v.type) {
1081-
case JS_FUNCTION:
1082-
JsFunction jf = new JsFunction(v.getValue());
1083-
v = new Variable(jf);
1084-
break;
1085-
case MAP:
1086-
case LIST:
1087-
Object o = recurseAndDetachAndDeepClone(v.getValue(), seen);
1088-
v = new Variable(o);
1089-
break;
1090-
default:
1091-
// do nothing
1092-
}
1093-
detached.put(k, v);
1069+
Object o = recurseAndDetachAndDeepClone(v.getValue(), seen);
1070+
detached.put(k, new Variable(o));
10941071
});
10951072
return detached;
10961073
}
10971074

10981075
// only called by "call" routine
1099-
protected void recurseAndAttach(Object o) {
1076+
protected void recurseAndAttach(String name, Object o) {
11001077
Set<Object> seen = Collections.newSetFromMap(new IdentityHashMap());
1101-
synchronized (runtime.featureRuntime.suite) {
1102-
recurseAndAttach(o, seen);
1103-
}
1078+
recurseAndAttach(name, o, seen);
11041079
}
11051080

1106-
private Object recurseAndAttach(Object o, Set<Object> seen) {
1081+
private Object recurseAndAttach(String name, Object o, Set<Object> seen) {
11071082
if (o instanceof Value) {
11081083
Value value = Value.asValue(o);
11091084
try {
11101085
if (value.canExecute()) {
11111086
if (value.isMetaObject()) { // js function
11121087
return attach(value);
11131088
} else { // java function
1114-
return new JsExecutable(value);
1089+
return value;
11151090
}
11161091
} else { // anything else, including java-type references
11171092
return value;
11181093
}
11191094
} catch (Exception e) {
1120-
logger.warn("[attach] failed to attach js value: {}", e.getMessage());
1095+
logger.warn("[*** attach ***] failed to attach js value: {} - {}", name, e.getMessage());
11211096
return null;
11221097
}
11231098
} else if (o instanceof JsFunction) {
@@ -1129,7 +1104,7 @@ private Object recurseAndAttach(Object o, Set<Object> seen) {
11291104
int count = list.size();
11301105
for (int i = 0; i < count; i++) {
11311106
Object child = list.get(i);
1132-
Object result = recurseAndAttach(child, seen);
1107+
Object result = recurseAndAttach(name + "[" + i + "]", child, seen);
11331108
if (result != null) {
11341109
list.set(i, result);
11351110
}
@@ -1140,7 +1115,7 @@ private Object recurseAndAttach(Object o, Set<Object> seen) {
11401115
if (seen.add(o)) {
11411116
Map<String, Object> map = (Map) o;
11421117
map.forEach((k, v) -> {
1143-
Object result = recurseAndAttach(v, seen);
1118+
Object result = recurseAndAttach(name + "." + k, v, seen);
11441119
if (result != null) {
11451120
map.put(k, result);
11461121
}
@@ -1162,11 +1137,10 @@ protected Object recurseAndAttachAndDeepClone(Object o) {
11621137

11631138
private Object recurseAndAttachAndDeepClone(Object o, Set<Object> seen) {
11641139
if (o instanceof Value) {
1165-
// will happen only for java "class" and java functions (static methods)
11661140
try {
11671141
return Value.asValue(o);
11681142
} catch (Exception e) {
1169-
logger.warn("[attach deep] failed to attach graal value: {}", e.getMessage());
1143+
logger.warn("[*** attach deep ***] failed to attach graal value: {}", e.getMessage());
11701144
return null;
11711145
}
11721146
}
@@ -1206,20 +1180,20 @@ protected Object recurseAndDetachAndDeepClone(Object o) {
12061180

12071181
private Object recurseAndDetachAndDeepClone(Object o, Set<Object> seen) {
12081182
if (o instanceof Value) {
1209-
Value value = Value.asValue(o);
1183+
Value value = (Value) o;
12101184
try {
12111185
if (value.canExecute()) {
12121186
if (value.isMetaObject()) { // js function
1213-
o = new JsFunction(value);
1187+
return new JsFunction(value);
12141188
} else { // java function
1215-
o = new JsExecutable(value);
1189+
return new JsExecutable(value);
12161190
}
12171191
} else {
12181192
// everything else including java-type references that do not need special attach handling
1219-
o = value;
1193+
o = JsValue.toJava(value);
12201194
}
12211195
} catch (Exception e) {
1222-
logger.warn("[detach] unsupported value in callonce / callSingle: {}", e.getMessage());
1196+
logger.warn("[*** detach deep ***] unsupported value in callonce / callSingle: {}", e.getMessage());
12231197
return null;
12241198
}
12251199
}
@@ -1327,7 +1301,13 @@ public void setVariables(Map<String, Object> map) {
13271301
if (map == null) {
13281302
return;
13291303
}
1330-
map.forEach((k, v) -> setVariable(k, v));
1304+
map.forEach((k, v) -> {
1305+
try {
1306+
setVariable(k, v);
1307+
} catch (Exception e) {
1308+
logger.warn("[*** set variables ***] skipping invalid graal value: {} - {}", k, e.getMessage());
1309+
}
1310+
});
13311311
}
13321312

13331313
private static Map<String, Variable> copy(Map<String, Variable> source, boolean deep) {
@@ -1953,7 +1933,7 @@ public Variable call(Variable called, Variable arg, boolean sharedScope) {
19531933
case FEATURE:
19541934
// will be always a map or a list of maps (loop call result)
19551935
Object callResult = callFeature(called.getValue(), arg, -1, sharedScope);
1956-
recurseAndAttach(callResult);
1936+
recurseAndAttach("", callResult);
19571937
return new Variable(callResult);
19581938
default:
19591939
throw new RuntimeException("not a callable feature or js function: " + called);

karate-core/src/main/java/com/intuit/karate/graal/JsValue.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,9 @@ public JsValue(Value v) {
121121
type = Type.OTHER;
122122
}
123123
} catch (Exception e) {
124-
logger.debug("js conversion failed", e);
124+
if (logger.isTraceEnabled()) {
125+
logger.trace("js conversion failed", e);
126+
}
125127
throw e;
126128
}
127129
}

0 commit comments

Comments
 (0)