-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: module for Polyglot Context injection #15
base: 1.0.x
Are you sure you want to change the base?
Conversation
It might be worth checking out the react code. I refactored it to be more general (btw the PR was never merged): micronaut-projects/micronaut-views#859 Look at It also has other useful utility classes like |
Some details regarding the Contexts:
The languages can have some usage constraints: JavaScript is a single threaded language, which means that only single thread can evaluate JavaScript code through single Python supports multi-threading and one can execute Python code from multiple threads at the same time, but internally Python uses "global" interpreter lock, so if two Java threads are executing Python code using the same However, different |
Sounds like we should pool contexts |
* @since 1.1.0 | ||
*/ | ||
@Experimental | ||
public class ContextProvider { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the comments on the PR, contexts should be pooled.
The best would be to have something like:
<R> R useContext(Function<Context, R> fn);
With the implementation:
- get the context from the pool
- invoke lambda
- return the context to the pool
- return the lambda result
WDYT @steve-s @mikehearn ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks nice. There is still one issue: you can get Java objects that wrap JavaScript/Python/... objects that are associated with given context. Example:
Value fun = useContext(ctx -> ctx.eval("js", "x => x + 1"));
fun.execute(42); // <-- this will execute the function in the `Context` where it originated from
thinking about this, I am not sure there can ever be some "compile-time safety net" for this, users will have to understand the constraints and make sure they do not hold onto Value
instances from the Context
outside of the lambda.
@mikehearn used try-with-resources for his Context
pool (but that doesn't solve this issue either).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Techically we can check what type is being returned from the method, but that would have to be an implementation specific check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Side note: it is even trickier with the proxy feature:
Value pythonClassInstance = ctx.eval("python", """
class MyPythonClass:
def foo(x): return x+1
MyPythonClass() # create instance
""")
MyJavaInterface javaProxy = pythonClassInstance.as(MyJavaInterface.class);
// now javaProxy looks like plain Java object, but internally it is backed by `Value`
assert javaProxy.foo(42) == 43 // evaluates Python function "foo" in the Context ctx
@steve-s and I put together this proof of concept for allowing users to inject Graal Languages Context into their application. I think using @ThreadLocal could good for this use case.
@steve-s will update you with details about the Context constraints.
Thoughts @fniephaus @mikehearn @dstepanov @graemerocher ?