Threading Problem with Nashorn
Benjamin Sieffert
benjamin.sieffert at metrigo.de
Mon Jul 15 01:18:32 PDT 2013
2013/7/13 Andrew Thompson <lordpixel+openjdk at mac.com>
>
> On Jul 9, 2013, at 6:34 AM, Attila Szegedi <attila.szegedi at oracle.com>
> wrote:
>
> > Actually, in your above example, since the JavaScript program has no
> explicit guarding of concurrent access to variable `i` you seem like you
> would actually even expect to have an engine that has "THREAD-ISOLATED" as
> its threading model instead of the simpler "MULTITHREADED" - that' very
> rare in an engine, usually hard to implement efficiently (do you clone all
> of the data up front? do you implement a copy-on-write semantics?) , and is
> functionally simpler to just have a non-threadsafe engine and let the users
> manage their own thread isolation by creating one engine instance per
> thread.
>
>
> In a model like that, what' s the best way to manage state?
>
> Assuming I want to make sure each invocation of eval() is unable to
> influence the next invocation - i.e. leave no ENGINE_SCOPE or GLOBAL_SCOPE
> behind between calls to eval, would it looks something like this:
>
> ThreadLocal<ScriptEngine> engine = ...
>
> ScriptContext sc = new SimpleScriptContext();
>
> engine.get().eval(someScript, sc);
>
> Is that a reasonable approach to getting isolation between eval() calls or
> is it overkill? Would creating new bindings be a better idea? This leaves
> leakage through GLOBAL_SCOPE but is GLOBAL_SCOPE visible to the JavaScript
> code?
>
> ScriptEngine e = engine.get();
> Bindings b = e.createBindings();
> e.eval(someScript, b);
>
> I am very interested in contrasting this with the worker model Jim Laskey
> posted about in the next message in this thread.
>
>
> AndyT (lordpixel - the cat who walks through walls)
> A little bigger on the inside
>
> (see you later space cowboy, you can't take the sky from me)
>
Hello,
I am working with Tobias on the project which inspired this topic and I'd
like to comment on your approaches and problems we found with them.
First, we'd really like to use CompiledScript, so in our case we tried a
ThreadLocal<CompiledScript>. As expected, this works correctly, though of
course leaves you with much overhead.
Concerning the second approach, we had little luck with using Bindings.
Iterating on the starting example again (
https://gist.github.com/tobsch/5955518), doing
public Double call() {
try {
SimpleBindings b = new SimpleBindings();
b.put("i", 0.0);
return (Double) onePlusOne.eval(b);
}
and removing "i = 0" from the javascript reproduces the same erronous
results.
Perhaps more interestingly (I noticed just yet, when adjusting the
example), writing
public Double call() {
try {
Bindings b = engine.createBindings();
b.put("i", 0.0);
return (Double) onePlusOne.eval(b);
}
results on "i" not being available to javascript. Passing empty bindings
and starting the script with "var i = 0" will solve this (js return value
has to be cast to Integer instead of Double then), but still yield
miscalculations.
This is, however, still using CompiledScript. Going your route and just
calling eval on the engine, passing the script and the bindings works
threadsafely.
More information about the nashorn-dev
mailing list