Closures not thread-safe?
Frantzius, Jörg
Joerg.Frantzius at aperto.com
Mon Feb 20 13:32:33 UTC 2017
Hi Joao,
the following test fails immediately for me with "java.lang.RuntimeException: Expected: Thread[ForkJoinPool.commonPool-worker-4,5,main], received: Thread[main,5,main]":
@Test
public void testClosureThreadSafety() throws ScriptException {
final ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
String testJsFunction = (
" (function outerFunction(currentThreadName) {\n" +
" function innerFunction() {\n" +
" return currentThreadName;\n" +
" }\n" +
" return innerFunction;\n" +
" })(java.lang.Thread.currentThread().toString())\n");
ScriptObjectMirror jsFunction = (ScriptObjectMirror) engine.eval(testJsFunction);
IntConsumer invokeAndTest = i-> {
String currentThreadName = Thread.currentThread().toString();
Object received = jsFunction.call(jsFunction);
if (!currentThreadName.equals(received)) {
throw new RuntimeException("Expected: " + currentThreadName + ", received: " + received);
}
};
IntStream.range(0, 10).parallel().forEach(invokeAndTest);
}
The outer function returns its inner function, which contains „currentThread“ as a reference to its closure (i.e. a reference to outerFunction’s „currentThread“ parameter). That closure property „currentThread“ will be set to the name of the current thread only once (in engine.eval(testJsFunction)), and subsequent calls to innerFunction will always return the name of that thread (and not of the current thread that calls innerFunction).
If your Javascript code is under your control, this may not be a problem, as you can change the code. In our case, we are using an existing Javascript library „Handlebars“ that we cannot change, which seems to be keeping function objects with closures around just like the above code does in Java.
Regards,
Jörg
Am 20.02.2017 um 13:00 schrieb João Paulo Varandas <joaovarandas at inpaas.com<mailto:joaovarandas at inpaas.com>>:
Hi Jorg.
Could you send us a code snippet?
I have never seem such problem when using closures. In my project, I use a single engine for whole web application. My tomcat is running with 150 maxThreads and it seems to be working fine. I test that in each build by running the test case below:
https://gist.github.com/joaovarandas/f80a9cb5548a9d620e4da1ace2729911
The idea in this test is to use a single engine and run a closure from one-thread or multiple-threads simultaneously and then read data from those closures.
PS.: Should I send the source code directly in the mail body for future readers?
[https://static.inpaas.com/assets/inpaas/images/logo-img-50px.png]
João Varandas
Arquiteto de Soluções Cloud
inPaaS - Idéias em Aplicações
p: +55 11 5091-2777 m: +55 11 99889-2321
a: Rua Nebraska, 443 - 1o Andar
Brooklin Paulista, São Paulo, SP
w: www.inpaas.com<http://www.inpaas.com/> e: joaovarandas at inpaas.com<mailto:joaovarandas at inpaas.com>
2017-02-19 18:30 GMT-03:00 Frantzius, Jörg <Joerg.Frantzius at aperto.com<mailto:Joerg.Frantzius at aperto.com>>:
… to correct myself, with code that contains closures, it’s probably global-per-thread on a single engine that remains as the least resource-consuming option (we were using a single global on single engine for all threads, in order to share expensively computed Javascript state between them).
From what I understand, global-per-thread could be implemented e.g. by having a ThreadLocal<ScriptContext> and always using that as the context in ScriptEngine.eval(script, context).
It would be good to know then whether global-per-thread on single engine still allows for sharing Nashorn’s code optimization between threads? That would already be great (and as Nashorn *is* great, I’m positive here :)
Regards,
Jörg
Am 19.02.2017 um 00:47 schrieb Frantzius, Jörg <Joerg.Frantzius at aperto.com<mailto:Joerg.Frantzius at aperto.com><mailto:Joerg.Frantzius at aperto.com<mailto:Joerg.Frantzius at aperto.com>>>:
Hi,
it begins to dawn on me that closures aren’t thread-safe, at least that would explain crosstalk issues we’re seeing in JMeter tests (with a single engine for multiple threads).
It would be good to know (and I guess for others as well) if somebody can confirm this?
Perhaps thread-safety of closures was thinkable if Nashorn somehow stored closure state in ThreadLocals, but I guess that’s neither happening nor planned?
From what I understand, closures are pervasive in Javascript code out there, and anybody using such code will currently be forced to use engine-per-thread.
Thanks for any hints,
Jörg
---
Dipl. Inf. Jörg von Frantzius, Technical Director
E-Mail joerg.frantzius at aperto.com<mailto:joerg.frantzius at aperto.com><mailto:joerg.frantzius at aperto.com<mailto:joerg.frantzius at aperto.com>>
Phone +49 30 283921-318<tel:%2B49%2030%20283921-318>
Fax +49 30 283921-29<tel:%2B49%2030%20283921-29>
Aperto GmbH – An IBM Company
Chausseestraße 5, D-10115 Berlin
http://www.aperto.com<http://www.aperto.com/><http://www.aperto.de/>
http://www.facebook.com/aperto
https://www.xing.com/companies/apertoag
HRB 77049 B, AG Berlin Charlottenburg
Geschäftsführer: Dirk Buddensiek, Kai Großmann, Stephan Haagen, Daniel Simon
---
Dipl. Inf. Jörg von Frantzius, Technical Director
E-Mail joerg.frantzius at aperto.com<mailto:joerg.frantzius at aperto.com>
Phone +49 30 283921-318<tel:%2B49%2030%20283921-318>
Fax +49 30 283921-29<tel:%2B49%2030%20283921-29>
Aperto GmbH – An IBM Company
Chausseestraße 5, D-10115 Berlin
http://www.aperto.com<http://www.aperto.com/><http://www.aperto.de/>
http://www.facebook.com/aperto
https://www.xing.com/companies/apertoag
HRB 77049 B, AG Berlin Charlottenburg
Geschäftsführer: Dirk Buddensiek, Kai Großmann, Stephan Haagen, Daniel Simon
"Esta mensagem, incluindo seus anexos, pode conter informacoes confidenciais e privilegiadas.
Se voce a recebeu por engano, solicitamos que a apague e avise o remetente imediatamente.
Opinioes ou informacoes aqui contidas nao refletem necessariamente a posicao oficial da Plusoft."
"Antes de imprimir, pense em sua responsabilidade e compromisso com o MEIO AMBIENTE"
---
Dipl. Inf. Jörg von Frantzius, Technical Director
E-Mail joerg.frantzius at aperto.com
Phone +49 30 283921-318
Fax +49 30 283921-29
Aperto GmbH – An IBM Company
Chausseestraße 5, D-10115 Berlin
http://www.aperto.com<http://www.aperto.de/>
http://www.facebook.com/aperto
https://www.xing.com/companies/apertoag
HRB 77049 B, AG Berlin Charlottenburg
Geschäftsführer: Dirk Buddensiek, Kai Großmann, Stephan Haagen, Daniel Simon
More information about the nashorn-dev
mailing list