Skip to content

Commit

Permalink
solution to avoid locking js functions #2329 #1883
Browse files Browse the repository at this point in the history
  • Loading branch information
ptrthomas committed Aug 9, 2023
1 parent edab030 commit 81b7fee
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import com.intuit.karate.StringUtils;
import com.intuit.karate.XmlUtils;
import com.intuit.karate.graal.JsEngine;
import com.intuit.karate.graal.JsFunction;
import com.intuit.karate.graal.JsLambda;
import com.intuit.karate.graal.JsList;
import com.intuit.karate.graal.JsMap;
Expand Down Expand Up @@ -1129,6 +1130,20 @@ public WebSocketClient webSocketBinary(String url, Value listener, Value value)
options.setBinaryHandler(handler);
return engine.webSocket(options);
}

public Object wrapFunction(Value value) {
if (value.isProxyObject()) {
Object o = value.asProxyObject();
if (o instanceof JsFunction) {
JsFunction fun = (JsFunction) o;
return JsFunction.wrap(fun.getValue());
}
}
if (value.canExecute()) {
return JsFunction.wrap(value);
}
throw new RuntimeException("js function expected");
}

public File write(Object o, String path) {
ScenarioEngine engine = getEngine();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,10 @@ public static void set(ScenarioEngine se) {
protected static void remove() {
THREAD_LOCAL.remove();
}

public JsEngine getJsEngine() {
return JS;
}

// engine ==================================================================
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ public JsEngine copy() {
return temp;
}

private Value attach(Value value) {
public Value attach(Value value) {
try {
return context.asValue(value);
} catch (Exception e) {
Expand Down
33 changes: 29 additions & 4 deletions karate-core/src/main/java/com/intuit/karate/graal/JsFunction.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,34 @@
*/
package com.intuit.karate.graal;

import com.intuit.karate.core.ScenarioEngine;
import org.graalvm.polyglot.Value;
import org.graalvm.polyglot.proxy.ProxyExecutable;
import org.graalvm.polyglot.proxy.ProxyInstantiable;
import org.graalvm.polyglot.proxy.ProxyObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
*
* @author peter
*/
public abstract class JsFunction implements ProxyObject {

protected static final Logger logger = LoggerFactory.getLogger(JsFunction.class);

public static final Object LOCK = new Object();

protected final Value value;
protected final CharSequence source;

protected JsFunction(Value v) {
this.value = v;
source = "(" + value.getSourceLocation().getCharacters() + ")";
}

public static ProxyExecutable wrap(Value value) {
return new Executable(value, true);
}

public Value getValue() {
Expand Down Expand Up @@ -73,8 +84,15 @@ public boolean removeMember(String key) {

protected static class Executable extends JsFunction implements ProxyExecutable {

private final boolean lock;

protected Executable(Value value) {
this(value, false);
}

protected Executable(Value value, boolean lock) {
super(value);
this.lock = lock;
}

@Override
Expand All @@ -83,9 +101,18 @@ public Object execute(Value... args) {
for (int i = 0; i < newArgs.length; i++) {
newArgs[i] = JsValue.fromJava(args[i]);
}
synchronized (LOCK) {
if (lock) {
synchronized (LOCK) {
return new JsValue(value.execute(newArgs)).value;
}
}
ScenarioEngine se = ScenarioEngine.get();
JsEngine je = se == null ? null : se.getJsEngine();
if (je == null || je.context.equals(value.getContext())) {
return new JsValue(value.execute(newArgs)).value;
}
Value attached = je.evalForValue("(" + source + ")");
return new JsValue(attached.execute(newArgs)).value;
}

}
Expand All @@ -102,9 +129,7 @@ public Object newInstance(Value... args) {
for (int i = 0; i < newArgs.length; i++) {
newArgs[i] = JsValue.fromJava(args[i]);
}
synchronized (LOCK) {
return new JsValue(value.execute(newArgs)).value;
}
return new JsValue(value.execute(newArgs)).value;
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,12 @@
import java.util.function.Consumer;
import java.util.function.Function;
import org.graalvm.polyglot.Value;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
*
* @author pthomas3
*/
public class JsLambda extends JsFunction.Instantiable implements Consumer, Function, Runnable {

private static final Logger logger = LoggerFactory.getLogger(JsLambda.class);
public class JsLambda extends JsFunction.Instantiable implements Consumer, Function, Runnable {

public JsLambda(Value v) {
super(v);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ Feature:

Scenario:
* def sayHello = function() { return 'hello world!' }
* def reuseExistingFunction =
* def temp =
"""
function() {
return sayHello();
}
"""
* def reuseExistingFunction = karate.wrapFunction(temp)
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ Feature:
@setup
Scenario:
* def data = read('data.csv')
* def exclude = x => data.filter(y => y.id != x)
* def include = x => data.filter(y => y.id == x)
* def exclude = karate.wrapFunction(x => data.filter(y => y.id != x))
* def include = karate.wrapFunction(x => data.filter(y => y.id == x))

Scenario Outline:
* assert id != '0'
Expand Down

0 comments on commit 81b7fee

Please sign in to comment.