Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does NodeJS have any plans for shared memory? #560

Closed
hitsthings opened this issue Apr 4, 2017 · 35 comments
Closed

Does NodeJS have any plans for shared memory? #560

hitsthings opened this issue Apr 4, 2017 · 35 comments

Comments

@hitsthings
Copy link

So this API is being added to JS that allows different execution contexts to share a chunk of memory safely with interleaved access.
Meanwhile the Web Worker spec already exists for creating these separate execution contexts.

I know there are pre-existing user space modules for web-worker implementations. But they either 1) use separate processes for each thread (and thus can't really share memory well), or 2) they literally expose all memory to all threads and thus accept all the chaos that other multithreaded languages often have.

Combined, the Web Worker and Shared Memory APIs seem like a solid infrastructure to build multithreading on. There would be no bad interaction with old code since the old code would have to opt in to using the shared buffer (or a bad dev would have to pass a shared buffer to the old code and then write to it). Is there any plan for making use of shared memory and web workers in Node?

@bnoordhuis
Copy link
Member

Is there any plan for making use of shared memory and web workers in Node?

Not at the moment. It's not completely out of the question but:

  1. Web workers are straightforward to implement through a native module. If the existing modules aren't any good, that doesn't mean it's impossible, just that no one has done it yet.

  2. Cross-platform shared memory and synchronization is a bit of a viper's nest. Node would have to support it out of the box on all the platforms it supports, a native module can get away with supporting just the three major ones: Linux, Windows, TOSFKAOSX (The Operating System Formerly Known As OS X.)

@hitsthings
Copy link
Author

Thanks for the info :) Wasn't expecting such a fast answer. Thanks for the alternative of a native module, too!

@addaleax
Copy link
Member

addaleax commented Apr 4, 2017

@hitsthings
Copy link
Author

Thanks @addaleax ! I was under the impression those threads still shared memory, but sounds like I'm wrong. Also I realized that I kinda completely forgot about https://nodejs.org/api/vm.html and this whole thing is probably just a derp. Thanks for setting me straight!

@sam-github
Copy link

I don't know what a derp is, but the VM API is completely unrelated to threading or concurrency.

@hitsthings
Copy link
Author

hitsthings commented Apr 4, 2017 via email

@bnoordhuis
Copy link
Member

@hitsthings Contexts are tied to their isolates, and those are not thread-safe. That is, you can't have two contexts in the same isolate and access them from different threads.

(You can pass SharedArrayBuffers between contexts but there won't be any real concurrency, it'll be strictly sequential.)

@ORESoftware
Copy link

ORESoftware commented Apr 4, 2017

@hitsthings I would highly recommend just using different node.js processes instead of the node-webworker-threads lib; unfortunately the node-webworker-threads lib is not very stable and has major API deficiencies last time I checked.

@hitsthings
Copy link
Author

Thanks, I get that separate processes is the current standard. I posted this originally because shared memory seemed like a great opportunity for threads. Most cases are good with share-nothing concurrency which is what you get with processes (and anything you want to pass between them is slower over IPC afaik). I had a case a few years back where I was trying to implement real-time tracking and mapping for nodecopters (for fun, so meh on stability). One big performance hurdle was that I needed to pass large chunks of image data, edge detection data, etc between processes. That's where threads would help since I wouldn't have to pass anything around to access it in multiple threads.

To be clear - I'm not asking about doing anything in production code. Was just curious about whether there were any ideas/plans for threading with sharedArrayBuffers in node that might help me with problems like that.

Ben - thanks for the VM clarification.

@sam-github
Copy link

you can share memory between processes as well as between threads, bunch of stuff on npmjs, I vouch for the quality of none of it :-) https://www.npmjs.com/search?q=shared+memory

@icodeforlove
Copy link

Would love to see some sort of equivalent for Workers, transferable objects and SharedArrayBuffer's.

node-webworker-threads is probably the closet you can get at the moment and from my experience its fairly unstable.

As it currently stands it is easier to take advantage of all cores and memory in the browser vs node. Which makes me sad :(.

@addaleax
Copy link
Member

@icodeforlove Hey, just so you are aware: nodejs/node#13143, https://github.com/nodejs/worker. :)

@refack
Copy link

refack commented May 25, 2017

@icodeforlove Hey, just so you are aware: nodejs/node#13143, https://github.com/nodejs/worker. :)

@addaleax talk about "hitting the nail of the head" 😄
@icodeforlove You are most welcome to participate in the discussion (esp. nodejs/worker#1)

@Pacerier
Copy link

Pacerier commented Jul 21, 2017

@ORESoftware, @addaleax, That's not shared memory. It's using message parsing which is slow.

@Pacerier
Copy link

Pacerier commented Jul 21, 2017

I've been waiting for this for a loong time, when will they decide to implement this?

Lack of shared memory capability is a dealbreaker, making me choose Java instead of Node for server apps.

@gireeshpunathil
Copy link
Member

Linking this one with 14158 which is potentially capable of covering this requirement.

@refack
Copy link

refack commented Jul 21, 2017

Linking this one with 14158 which is potentially capable of covering this requirement.

Just to make that clearer — nodejs/node#14158 is a discussion about better supporting the embedding of node, in-process into other apps. It covers the use case of single process memory sharing, and also allows the embedder to implement inter-process memory sharing.

@p3x-robot
Copy link

I think the NodeJs arhitecture is not for threads, the is 2017, not like 1990 when they created Java some other languages. Thread is slow like hell.

Threads are dead.

@runvnc
Copy link

runvnc commented Aug 30, 2017

Isn't SharedArrayBuffer part of V8? Apparently not.
If Node won't add that stuff then once people are used to those features being available in the browser and they can't find it in Node then they will start just like running headless Chrome on the server in order to get those features.

@runvnc
Copy link

runvnc commented Aug 30, 2017

Which is obviously a pretty wonky hack to work around missing features.

@p3x-robot
Copy link

that's true, just for me it never be needed.

@runvnc
Copy link

runvnc commented Aug 30, 2017

After people get used to taking advantage of it in the browser, the sentiment will go pretty quickly from 'who needs this they must not know how to Node' to "why the heck didn't they implement this already".

@p3x-robot
Copy link

SharedArrayBuffer, haha, when we are building cluster system in different contents with shared data :)

@Pacerier
Copy link

Pacerier commented Oct 4, 2017

@p3x-robot Re "haha" Meaning?

@p3x-robot
Copy link

i guess, i started using redis, multiple nodes of process and servers and for me SharedArrayBuffer is dropped out totally. Just for me it looks like it is unnecessary. You can't use the SharedArrayBuffer with a cluster node any way. It is even easier to use just process.nextTick if you want just 1 process, process.nextTick is totally what is for, instead threads. For me the thread is dead. I uses processes and clusters and nodes. Look at nginx, bind9, tons of biggest programs are using multiple process by number of core of cpu. If you want to shared data, you can use redis, memcached etc... Needless to wait for SharedArrayBuffer, it is almost useless. Node is a very well thought architecture and it is non blocking solution instead of 1000 threads and tons of memory.
Look IDEA, I use even they helped me with updating the IDEA registry from 30 threads at once to 1000. But all it needs just another process outside of IDEA instead of 1 process.
This is why it is slow.
image
Look at CHROME, they are using processes as well and it is still the fastest and best browser.
EDGE and Firefox is slow with their thread architecture

I know it is my thinking, of course threads are good, but that's all, just an opinion.
There will be an even better solution, but for me NODEJS is the god, besides if it is really important, today it is easy to write N-API with threads with C++ ( I dropped C, C++ is enough fast and easier then C).

But, you can think totally the other side.
process.nextTick is the same es a thread and the speed is totally the same or faster then a share data.

@Pacerier
Copy link

Pacerier commented Oct 12, 2017

@runvnc, re "running headless Chrome on the server"; but what if ⨕ there's Oracle and its billions of $$ on proper Java support for real shared memory?

@p3x-robot
Copy link

https://github.com/Microsoft/napajs/

@allenluce
Copy link

While it's not a general solution, I ended up writing a module (in C++) to handle shared memory. It produces objects backed by a key-value store kept in shared memory.

@p3x-robot
Copy link

p3x-robot commented Nov 21, 2017

i think redis is faster then a file based solution. it is already there, why you guys want threads and share buffers, when process-es are faster and process.send is fast, besides redis is awesome as well.

all people are thinking like java and c++.

this is nodejs. :) 👍 💯 🥇

@allenluce
Copy link

Direct access to (shared) memory is definitely faster than either Redis or process.send (which uses a Unix domain socket underneath, at least on my Mac). This is especially true in the case of random accesses and even more so when no synchronization is required (i.e. in the read-only case). I was led to mmap-object after finding that Redis was far too slow for my application (even when configured to use Unix domain sockets).

@mogill
Copy link

mogill commented Dec 17, 2017

It is telling people continue to comment on this issue more than 8 months after it was closed. Experimentation with parallelism and shared memory in Node has been ongoing for years, and there is a diverse set of implementations for curious programmers to evaluate and use.

I created a List of Parallel JS Projects that compares the various approaches. Some of these tools may be useful until there is built-in support.

@Pacerier
Copy link

Pacerier commented May 13, 2018

@p3x-robot, re "process.send is fast"; Ever did graphics and other baremetal code before?

Re "why"; Because whatever's fast today is slow tomorrow as demands can only go up.

Fact is NodeJS will remain a "kiddy" tool until it can do proper multi-processing.

@p3x-robot
Copy link

if you want speed, you use c++, if you want functional, use js, that's all.
shared memory with javascript, compare to c++...
javascript is never be fast, it is functional language, not the most functional , but the best.
and c++ is not the fastest, but still the best usable.
but the best overall javascript and c++ is the best duo.

why do i would want to speed out of js??? it is a VM....
image processing is C++ , not js memory shared...
now how you receive the data is up to you.

not how you receive the data, but have you process big large of data.
js can receive 1 GB, if the processing is in C++.

i am settled with js with c++
you can always go to up to OCaml and down to assembly....

if you receive with shared memory or with process.send or a file, db, not so big problem.
of course, i think we can optimize shared memory, but enough processing this and that...

i think i never think about threads etc. etc. etc.
besides sometimes you have it's own server for processing video, and different web server, db... farms, clusters, i lost thinking in one machine...

we all think on 1 server.
think of farms ... ???

how do you use shared memory with different servers???

i think, it is an interesting QUEST!!! 🔢

@Pacerier
Copy link

Pacerier commented May 15, 2018

@p3x-robot , NodeJS wants to replace Java/C++/PHP/C/ASM/etc (other "server-side" environments). But it simply can't until it can do proper multi-processing.

Re "how do you use shared memory with different servers"; It can be built the same way everything else is built as long as you first have shared memory on a single server. Without which, anything built will be slow.

@kyr0
Copy link

kyr0 commented Dec 14, 2021

@allenluce Still people are suffering here :D My solution uses shared memory device shm (Linux, macOS / virtual shared memory page (Windows) based on my project libsharedmemory --> node-libsharedmemory

If we'd merge our code bases, we could simply use my lib as the backend instead of your impl. and get the holy grail of a real shared memory for Node.js. Do you or anyone else have time and energy to join? :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests