Skip to content

Commit

Permalink
Fixes polylgot context handling when mixing languages.
Browse files Browse the repository at this point in the history
Improves context caching.
  • Loading branch information
ckramp committed May 15, 2024
1 parent 5532711 commit c5c7919
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public ProxyExecutable getProxyExecutable(final ActionContext actionContext, fin

if (!engineName.isEmpty()) {
final SecurityContext securityContext = actionContext.getSecurityContext();
final Context context = Context.getCurrent();
final Context context = ContextFactory.getContext(engineName, actionContext, entity);
final Value bindings = context.getBindings(engineName).getMember("Structr");
final StructrBinding binding = bindings.asProxyObject();
final GraphObject previousEntity = binding.getEntity();
Expand All @@ -108,6 +108,7 @@ public ProxyExecutable getProxyExecutable(final ActionContext actionContext, fin
final Arguments args = Arguments.fromValues(actionContext, arguments);
final Arguments converted = checkAndConvertArguments(securityContext, args, true);
final ActionContext inner = new ActionContext(securityContext, converted.toMap());
inner.setScriptingContexts(actionContext.getScriptingContexts());

if (arguments.length == 1) {
binding.setMethodParameters(arguments[0]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Engine;
import org.slf4j.LoggerFactory;
import org.structr.api.config.Settings;
import org.structr.common.error.FrameworkException;
import org.structr.core.GraphObject;
Expand Down Expand Up @@ -120,41 +121,41 @@ public static Context getContext(final String language, final ActionContext acti
switch (language) {

case "js":
return getAndUpdateContext(language, actionContext, entity, ()->buildJSContext(actionContext, entity));
return getOrCreateContext(language, actionContext, entity, ()->buildJSContext(actionContext, entity));

case "python":
return getAndUpdateContext(language, actionContext, entity, ()->buildPythonContext(actionContext, entity));
return getOrCreateContext(language, actionContext, entity, ()->buildPythonContext(actionContext, entity));

case "R":
return getAndUpdateContext(language, actionContext, entity, ()->buildGenericContext(language, actionContext, entity));
return getOrCreateContext(language, actionContext, entity, ()->buildGenericContext(language, actionContext, entity));

default:
throw new FrameworkException(500, "Could not initialize context for language: " + language);
}
}

private static Context getAndUpdateContext(final String language, final ActionContext actionContext, final GraphObject entity, final Callable<Context> contextCreationFunc) throws FrameworkException {
private static Context getOrCreateContext(final String language, final ActionContext actionContext, final GraphObject entity, final Callable<Context> contextCreationFunc) throws FrameworkException {

Context storedContext = actionContext != null ? actionContext.getScriptingContext(language) : null;

if (actionContext != null && storedContext != null) {

storedContext = updateBindings(storedContext, language, actionContext, entity);
actionContext.putScriptingContext(language, storedContext);

} else {
if (actionContext != null && storedContext == null) {

try {

storedContext = contextCreationFunc.call();
updateBindings(storedContext, language, actionContext, entity);
actionContext.putScriptingContext(language, storedContext);

} catch (Exception ex) {

ex.printStackTrace();

LoggerFactory.getLogger(ContextFactory.class).error("Unexpected exception while initializing language context for language \"{}\".", language, ex);
throw new FrameworkException(500, "Exception while trying to initialize new context for language: " + language + ". Cause: " + ex.getMessage());
}
} else if (actionContext != null) {

// If binding exists in context, ensure entity is up to date
final StructrBinding structrBinding = storedContext.getBindings(language).getMember("Structr").asProxyObject();
structrBinding.setEntity(entity);
}

return storedContext;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public class ActionContext {
public static final String SESSION_ATTRIBUTE_PREFIX = "user.";

// Regular members
private final Map<String, Context> scriptingContexts = new HashMap<>();
private Map<String, Context> scriptingContexts = new HashMap<>();
private final ContextStore temporaryContextStore = new ContextStore();
private final StringBuilder outputBuffer = new StringBuilder();
private ErrorBuffer errorBuffer = new ErrorBuffer();
Expand Down Expand Up @@ -643,6 +643,14 @@ public void putScriptingContext(final String language, final Context context) {
scriptingContexts.put(language, context);
}

public void setScriptingContexts(final Map<String, Context> contexts) {
scriptingContexts = contexts;
}

public Map<String,Context> getScriptingContexts() {
return scriptingContexts;
}

public boolean isRenderContext() {
return false;

Expand Down

0 comments on commit c5c7919

Please sign in to comment.