eval is not thread safe. Added lock to avoid 'No such function invokeInternalXXX' exception (#4211)

* eval is not thread safe. Added lock to avoid 'No such function invokeInternalXXX' exception

* License fix
This commit is contained in:
VoBa 2021-03-05 18:18:58 +02:00 committed by GitHub
parent 6789cff802
commit 953054fadc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -40,6 +40,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
@Slf4j @Slf4j
public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeService { public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeService {
@ -56,6 +57,8 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer
private final FutureCallback<UUID> evalCallback = new JsStatCallback<>(jsEvalMsgs, jsTimeoutMsgs, jsFailedMsgs); private final FutureCallback<UUID> evalCallback = new JsStatCallback<>(jsEvalMsgs, jsTimeoutMsgs, jsFailedMsgs);
private final FutureCallback<Object> invokeCallback = new JsStatCallback<>(jsInvokeMsgs, jsTimeoutMsgs, jsFailedMsgs); private final FutureCallback<Object> invokeCallback = new JsStatCallback<>(jsInvokeMsgs, jsTimeoutMsgs, jsFailedMsgs);
private final ReentrantLock evalLock = new ReentrantLock();
@Getter @Getter
private final JsExecutorService jsExecutor; private final JsExecutorService jsExecutor;
@ -120,12 +123,17 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer
protected ListenableFuture<UUID> doEval(UUID scriptId, String functionName, String jsScript) { protected ListenableFuture<UUID> doEval(UUID scriptId, String functionName, String jsScript) {
jsPushedMsgs.incrementAndGet(); jsPushedMsgs.incrementAndGet();
ListenableFuture<UUID> result = jsExecutor.executeAsync(() -> { ListenableFuture<UUID> result = jsExecutor.executeAsync(() -> {
try {
evalLock.lock();
try { try {
if (useJsSandbox()) { if (useJsSandbox()) {
sandbox.eval(jsScript); sandbox.eval(jsScript);
} else { } else {
engine.eval(jsScript); engine.eval(jsScript);
} }
} finally {
evalLock.unlock();
}
scriptIdToNameMap.put(scriptId, functionName); scriptIdToNameMap.put(scriptId, functionName);
return scriptId; return scriptId;
} catch (Exception e) { } catch (Exception e) {