How do I create and implement a non-blocking memory display module for node.js

There is a mmap module for node.js: https://github.com/bnoordhuis/node-mmap/

As Ben Noordhuis wrote, the available mapped memory may be blocked, so he no longer recommends it and discontinued it.

So interesting, how do I create a non-blocking memory display module for node.js? Threading, Fibers ,?

Obviously, this is adjacent to the question of whether the thread in node.js will just happen elsewhere instead of the request handler.

+7
memory-mapped-files mmap memory-mapping
source share
1 answer

Speaking of introducing a native object in non-blocking mode, the first place to look is libuv . This is how the node base modules interact with the base platform. Of particular interest is the API work queue .

If we quickly look at node-mmap source , we see that it is actually very simple. It calls mmap and returns node Buffer , which wraps the area of ​​mapped memory.

Reading from this Buffer is what causes the OS to perform I / O. Since this is bound to happen in the JS stream, we end up blocking the JS stream with disk I / O.

Instead of returning a Buffer that allows JS direct access to the associated memory, you should write a shell class in C ++ that the marshals read and write through the work queue. Thus, disk I / O will be performed in a separate thread.

In JS, you will use it something like this:

 fs.open('/path/to/file', 'r', function(err, fd) { fs.fstat(fd, function(err, stats) { var mapped = mmap.map(stats.size, mmap.PROT_READ, mmap.MAP_SHARED, fd, 0); mapped.read(start, len, function(err, data) { // ... }); }); }); 

And in C, the read function would create a libuv worker request and queue the worker queue. Then, the working function C reads the displayed memory range (based on the specifications of the caller), which can cause disk I / O, but it is safe because it happens in a separate thread.

What will happen next is interesting. A safe approach would be for a working alloc to create a new block of memory and memcpy from the associated memory. The worker then passes the pointer to the copy, and the C callback completes it in the Buffer , which should be returned to JS-land.

You can also try to read the range (so that any necessary I / O operations occur in the workflow), but actually did nothing with the data, and then using the C callback, just wrap the displayed memory range in Buffer . Theoretically, the parts of the file that the worker read will remain in RAM, so access to this part of the associated memory will not be blocked. However, I honestly don’t know enough about the memory card to say if this could end up biting you.


Finally, I doubt whether this will really provide extra performance on the node with the usual fs methods. I would only go this way if I did what really justifies using mmap .

+9
source share

All Articles