Open mfreeman-xtivia opened 8 years ago
Hmm that's a fair point. It probably makes sense to expose an overload of enable
that takes a Binding
instead of the engine itself.
If you look at the code it's mostly using the engine to retrieve the global bindings (I'm not sure the other stuff is really OK in fact). Quite a bit of confusion around Bindings with Nashorn, what with the magical "global per engine" stuff, etc.
I'm pretty busy as of now, but let's leave this bug open and I'll have a look when I get some time. Or I'll gladly accept a PR if you beat me to it :)
Martin, I was going to :-) but I got a little uncomfortable trying to unwind the Module class to figure out exactly where i would swap Engine over to Bindings. Maybe I will take another pass at it --
--for now I am simply firing up a complete engine/bindings/eval sequence per thread, which seems heavyweight and gross--in the end and as you suggest I would rather have just a single Engine and then be able to spin up a unique Bindings/eval per thread.
Ah indeed I kinda missed that the engine was being passed to Module
. Slightly more complex, but probably OK in the end.
One thing to know keep in mind though: even if you are re-using the same engine across all threads, you'll still need to start with new bindings for each request, meaning that each JS file you require
will need to be parsed & executed each time. That's still pretty intense...
In our case, we maintain a pool of engines & bindings, accepting the fact that globals might be re-used across several requests, which is not problematic in the context where we're using it.
Yeah, i oversimplified when i said one per thread--for now I am running in a Tomcat environment and I spin up a new Engine and parse everything into it the first time I see a JS request on that thread then save it away based on thread ID--so a poor's mans thread pool for the moment with the penalty that the first request on thread X pays the startup price and then everything is read from a cache based on thread ID after that
Sooo......any code changes per this issue? or just closing to close?
Well I kinda stuck on the question at the start, and forgot that I said I might at some point look at using Bindings instead of an Engine. I'll re-open then.
In my use case, I have noticed a speed up by creating a singleton NashornScriptEngine and using separate SimpleBindings per thread/request. Enabling require() on my own bindings instead of ENGINE_SCOPE would be a great feature.
I may have some time soon to implement this.
I added an overload to Require
(see #19). I think it's all that's needed, but I might be wrong - it's been a long day. I'll revisit this tomorrow but if anybody wants to test and report results feel free.
This half works for me, the bindings that require is enabled on also needs to be used to eval the modules. My use case might be super special and might be violating encapsulation / abstraction for node style modules. I'll see if i can solve my problem w/ extending Module or registering a "binding provider" to Module or some such.
This is really a question--what is the best/right way to use this Require module in a multi-threaded servlet environment??
So believing based on what I've read that the Nashorn engine itself is threadsafe, I create a single one of those in my servlet init().
Then on each request/thread i create new bindings, map in Java objects to be exposed to the script(s), and then do engine.eval(mainscript,newbindings).
The challenge/question is where in that sequence do I put the Require.enable(engine)? once at init? It doesn't seem like Require class exposes a flavor of enable where i could pass in the bindings (global) i want it to use?