nodyn/nodyn — pull request #58 by malaporte (2014-07-03 20:09:16+00:00)
Title: Fix concurrency issues caused by JS callbacks running in different event loops

I had issues with a module using process.nextTick to defer some processing. It randomly failed because code protected by a run once flag ended up being called twice.

I did this quick test:

for (var i = 0; i < 10; ++i) {
process.nextTick(function() {
for (var i = 0; i < 1000; ++i) {
console.log(i);
}
});
}

I ended up with stuff like this:

773
795
774
796
775

Clearly the same JS context is running in parallel in multiple threads, and that's Not a Good Thing :)

I've had a look at the code and the problem was because the JS code initially ran inside a thread that wasn't bound to a specific event loop. So everytime the runInContext method was called a potentially different event loop was used from the event loop group (on my setup there are 8 of those).

Indeed, if I wrap my previous test in a process.nextTick, everything suddenly worked fine (since the thread from where the subsequent nextTicks are called is bound to an event loop).

So I slightly changed how the Main class runs the JS code to have it execute inside a runInContext.

For it to work I had to make a small change in DynJS, otherwise I couldn't cleanly hook at the correct spot. The other pull request is here: TODO

I also included a fix for tolerating multiple calls to end on a client request, to mimic Node's behavior.