nodejs / node

Node.js JavaScript runtime ✨🐢🚀✨

Home Page:https://nodejs.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.

You can see some of the pain caused by this looking at: request/request-promise#89