Description
(Pre-disclaimer, apologies if anything I say here is incorrect or overly alarmist. I think this is a real problem but I don't pretend to understand everything that's going on here, especially the Node and V8 codebase I'm not very familiar with.)
I've seen some problems in my NodeJS app using node-weak which seemed like they could only be explained by my code getting preempted by other JS code that changed state out from under it. I believe I've eventually traced this to the use of MakeCallback in Node's native code (src/node.cc); when it's called, it calls not only the callback you told it to call but also all registered nextTick callbacks. And node-weak invokes MakeCallback from GC, which basically means, from anywhere.
I started a thread about this on the NodeJS mailing list, too.
To the best of my evolving understanding, either
- MakeCallback should be taught to only invoke process._tickCallback when it was invoked directly from the libuv event loop, not if it was invoked by something like node-weak in a nested execution context
- MakeCallback is a dangerous API to expose to extension code directly, or at least needs to be better documented about when to use it and when to avoid it
- node-weak, when invoking the cleanup callback (and its "global" callback which I don't really understand), should invoke those callbacks directly instead of via MakeCallback
I don't mean to malign node-weak; it's very cool and very useful functionality, but this side effect of preempting code and executing pretty much arbitrary any other code during GC is quite alarming.