Make native module rerequirable.
waaaagit opened this issue · comments
I'm a node embedder, using node v4.2.4
In my situation,
sometimes, I need to unrequire module.(Which I delete module cache in require.cache).
sometimes, I need to refresh the global object to clean the symbol.
In those case,
the .node library probably loaded before. after unrequire module or refresh global object, I got error like 'non self-register'.
The pure JS module and the buildin module are FINE.
Simple test code:
require('iconv');
delete require.cache["C:\\Program Files (x86)\\nodejs\\node_modules\\iconv\\lib\\iconv.js"];
delete require.cache["C:\Program Files (x86)\nodejs\node_modules\iconv\build\Release\\iconv.node"];
require('iconv');
@waaaagit so you're wanting to be able to unload compiled native addons just like you can do with the require.cache
for JavaScript libraries?
I guess this means using uv_dlclose()
on a loaded lib, perhaps providing a process.dlclose()
as a reverse of process.dlopen()
. I'm not sure what the cross-platform consequences of this are and whether it would really unload an addon properly across the various OSs we support. Someone else might have to chime in on that question. @bnoordhuis, @saghul?
Actually, I wanting make native module rerequirable, not unload native module.
Because I use node's multi context feature. If a native module loaded in a context, it can't load by other context :(
I think this is not just a feature request, but also a bug for multi context feature.
@rvagg
OK, so this in src/node.cc is probably relevant:
// DLOpen is process.dlopen(module, filename).
// Used to load 'module.node' dynamically shared objects.
//
// FIXME(bnoordhuis) Not multi-context ready. TBD how to resolve the conflict
// when two contexts try to load the same shared object. Maybe have a shadow
// cache that's a plain C list or hash table that's shared across contexts?
Well, node has been supporting multi-context feature for a long time. I hope node embedders don't need to wait too long for this bug fix :)
There are two pieces to this issue. One is loading and unloading of shared objects in a multi-context environment, the other is making add-ons multi-context aware.
iconv
, for example, isn't currently multi-context ready but can be made to with little effort. Many other add-ons however have tons of global state and won't be so easy to adapt.
(Some dynamic linkers support loading a shared object more than once at different addresses. But it's not portable and won't help if the global state is something like a log file.)
Apropos core support, a NODE_MODULE_CONTEXT_AWARE
initializer macro for add-ons exists in src/node.h
but it hasn't been hooked up to process.dlopen()
yet. I don't have time (or, if I'm honest, inclination) to work on that but it shouldn't be hard to implement the machinery for it.
+1
You can see some of the pain caused by this looking at: request/request-promise#89
Put into https://github.com/nodejs/node/projects/13 backlog