Skip to content
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

How Best to Use in Servlet Environment? #12

Open
mfreeman-xtivia opened this issue Nov 14, 2016 · 9 comments
Open

How Best to Use in Servlet Environment? #12

mfreeman-xtivia opened this issue Nov 14, 2016 · 9 comments

Comments

@mfreeman-xtivia
Copy link

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?

@malaporte
Copy link
Owner

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 :)

@mfreeman-xtivia
Copy link
Author

mfreeman-xtivia commented Nov 18, 2016

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.

@malaporte
Copy link
Owner

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.

@mfreeman-xtivia
Copy link
Author

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

@ghost
Copy link

ghost commented Feb 8, 2017

Sooo......any code changes per this issue? or just closing to close?

@malaporte
Copy link
Owner

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.

@malaporte malaporte reopened this Feb 8, 2017
@kevbob1
Copy link
Contributor

kevbob1 commented Mar 13, 2017

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.

@malaporte
Copy link
Owner

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.

@kevbob1
Copy link
Contributor

kevbob1 commented Mar 15, 2017

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants