29 ms·
Napa.js: A multi-threaded JavaScript runtime
- Touche 9y agoThis looks a lot like web workers, which Node.js does not have. Hopefully they will add it. https://github.com/nodejs/worker/issues/2 https://github.com/nodejs/worker/issues/2
- je42 9y agofork works fine in node.js
- je42 9y agowhy down vote ? fork is fine as long as the communication between the two processes is low-bandwidth.
- Touche 9y agoIt works fine for many use cases but has serialization overhead.
- nevir 9y agoShared memory & low overhead sharing of expensive objects is probably the primary reason to use Napa
- MuffinFlavored 9y agoI don't think Napa features shared memory though, does it?
- daiyip 9y agoSince everything is in a single process, they can be shared via native structures. Each JS thread has its own heap, there will be a cost to transfer the shared native structures into JS object. For complex objects, usually JSON is used thus marshall/unmarshall is needed. But for objects like UTF-8 string or ArrayBuffer, the same layout is used across JS and C++, thus at almost no cost. Another thing is that between addon-modules, they can pass pointer of native structures (like Buffer) using 2 uint32 through JS. In this case, JS works as a binding language.
- deleted 9y ago[deleted]
- raresp 9y agoI was expecting something like this for a long time. Thanks!
- dtzur 9y agoShared memory!
- bertolo1988 9y agoYou can get rid of the need to multi threading by deploying more containers in the same machine or via orchestration. I don't understand why people keep insisting that the lack of multi threading support is a Javascript problem when there are better and more scalable ways of using your machine resources.
- CaveTech 9y agoA container per thread sounds like the least efficient solution possible.
- stingraycharles 9y agoAssuming everything you do is non-blocking, this effectively means a container per core. Not ideal, but not too bad either.
- stupidcar 9y agoAnd if it isn't non-blocking? What if I'm writing a game and want to run parts of the rendering, AI, physics, etc. in parallel? Do I create a bunch of containers for each subsystem of my game and have them all communicate via IPC? This doesn't sound like a recipe for good memory/performance characteristics.
- stingraycharles 9y agoBut we’re talking about javascript here, a language that is async about almost everything. I completely agree with what you’re saying for those other problems you describe. But for the typical node.js webapp, doing the one-container-per-core is perfectly fine.
- bertolo1988 9y agoIts not up to me to know how to manage processes or threads. That's the SO task, not mine. My app should be stateless and scale by replication. This is the most efficient solution in every possible way.
- jondubois 9y agoI think this could be useful but I really hope they get it right (especially the broadcast and other cross-worker communication features). Right now it looks like the broadcast feature cannot target specific workers - That's already a red flag. If they push too hard on thread locking and data consistency across workers, then it's not going to scale and it may lose all the advantages of being able to run on multiple CPU cores.
- daiyip 9y agoA key design goal is to make all workers within a zone symmetric, broadcasting/executing to specific workers is an anti-pattern. Please see: https://github.com/Microsoft/napajs/wiki/introduction#zone https://github.com/Microsoft/napajs/wiki/introduction#zone
- thom_nic 9y agoAny informed commentary on the pros/ cons of this vs cluster? As far as I can see, cluster workers are all uniform (no task-specific pools) and cluster has no broadcast (just `worker.send(message)`.)
- maxpert 9y agoCluster runs multiple processes, this is multi-threaded. So everything is isolated there, communication can happen only through IPC mechanisms, and high memory overhead. In case of threads its typical synchronization with of course shared memory side effects. It’s a typical thread vs process debate.
- maxpert 9y agoWait what? Why are they getting rid of simplicity and model that just works. Once again Microsoft managed to put on some C# programmers on JS. The first thing they thought was why doesn’t it support threads! Let’s build thread support and get a promotion! Edit: I would question usage of Node if everything you are doing is CPU bound. I think people started down-voting me without going through docs, I mean just read this documentation page and tell me this is right https://github.com/Microsoft/napajs/blob/master/docs/api/memory.md#memory-allocation-in-cpp-addon https://github.com/Microsoft/napajs/blob/master/docs/api/mem...
- shados 9y agoNot like they did it first. There's been a few multi threaded JS over the years, and shared memory types are part of the standard, so /shrugs
- chenzhekl 9y agoThe README expained it clearly > As it evolves, we find it useful to complement Node.js in CPU-bound tasks, with the capability of executing JavaScript in multiple V8 isolates and communicating between them. Not everything MS did was evil.
- couchand 9y agoIt's not evil it's just dumb. If your workload is CPU bound you probably shouldn't be running it in Node.js.
- fenwick67 9y agoThere are some cases on the threshold that this can be useful for. For example, let's say your Node application's requirements changed, and now you have to transform a set of five JSON objects to one JSON object, with some big arrays, indexing, and sorting required. The operation takes 10-100ms of cpu time, which isn't nuts, but with thousands of requests per second would normally be a catastrophe. If you can spawn a thread in this case you can save the day.
- deleted 9y ago[deleted]
- deleted 9y ago[deleted]
- Dinux 9y agoTook long enough for threads to reach JS as well
- chuckdries 9y agoI'm excited. My friend is working on extending rpgmaker, a game engine built on node. Say what you will about building a game engine on top of Node but this could be a very useful way to offload CPU heavy tasks from the main render thread
- polskibus 9y agoThis is far from the first attempt to do bring multithreading/parallelism into JS. A (failed) example: https://en.wikipedia.org/wiki/River_Trail_(JavaScript_engine) https://en.wikipedia.org/wiki/River_Trail_(JavaScript_engine... Another attempt (although a different approach) is here : https://github.com/tc39/ecmascript_sharedmem https://github.com/tc39/ecmascript_sharedmem Hopefully, Microsoft will learn from the errors of others. Interestingly, napa is build on V8, not on MS own javascript engine.
- appimonster 9y agoSounds great! Now, We can make memory efficient Electron with this kind of runtime. It will make JavaScript to be used in creating desktop application more reasonable.
- pc86 9y agoThere are many, many tools for creating great desktop applications. Why would using JavaScript for this ever be reasonable?
- k3liutZu 9y agoTo share the same codebase across Windows, macOS, linux, browser
- seba_dos1 9y agoSo, instead of writing great multiplatform desktop app in, say, Qt, and writing great Web frontend, you write half-baked desktop-web hybrid that doesn't feel great anywhere. Awesome.
- endless1234 9y agoAtom and VS Code don't "feel great"? Yes, there are lots of shitty Electron apps out there, but don't the good ones prove that it's possible to write good ones too?
- kls 9y agoI would throw GitKracken in the pot, with apps done well using Electron.
- GordonS 9y agoI'm with you here. Electron has gotten a bad name thanks to resource hogs like Slack, but it can also be used to create amazing multi-platfotm desktop apps. VS Code is a great example of Electron done right - compared to the full VS it absolutely flies, while still being packed with features and being very extensible.
- diegoperini 9y agoIs this multi threaded Node workers that can only share read access to their parent process' pid?
- maxpert 9y agoNops pure threads inside a process.
- diegoperini 9y agoIs hiding the mutable shared memory and introducing mandatory serialization for message passing a design decision or technical limitation of v8?
- christophilus 9y agoThis is interesting. I see some negativity in the comments, but I think this was really a missing piece of the Node ecosystem, and I hope this solution ends up getting good adoption. On a slightly related note, I wonder if ClojureScript + Node would be the best way to take advantage of this. Has anyone here used ClojureScript with Node?
- cormacrelf 9y agoIf you were wanting multithreaded Clojure, you're probably already using the JVM. It's much more mature and performant and tunable for that use case.
- christophilus 9y agoTrue! One thing I have noticed, though, is that a lot of Clojure code is blocking (database drivers, and such), so some subset of problems might be easier to write on Node. In addition, we are currently running Node in production, but not the JVM, so targeting Node with ClojureScript is an easier sell than creating a whole new deployment target.
- z3t4 9y agoLooks almost the same as something using fork and message passing, which also scales over several machines. The examples should show use cases that use shared memory or examples where it wouln't be possible to use worker processes.
- nevir 9y agoV8 doesn't support (real) forking, unfortunately
- j_s 9y agoI will circle back in a year or so to see if this 'sticks' -- very few Microsoft open source projects provide enough value / demonstrate enough inertia this early in their lifecycle to justify any investment on my part. https://github.com/MicrosoftArchive/redis/issues/556 https://github.com/MicrosoftArchive/redis/issues/556 (Jun-Sep 2017) >Why do MS always do this??? Start something, announce it aloud "we are now open source, we are now this and that blah blah" then quietly do a 360 and moonwalk away
- panta 9y agoPerhaps a 180? :-)
- smnscu 9y agoMy reaction exactly, but it's actually a joke. > do a 360 and moonwalk away
- j_s 9y agoTo be clear for non-Michael-Jackson-fans: 360 + moonwalk works out the same (by sliding away backwards). https://en.wikipedia.org/wiki/Moonwalk_%28dance%29 https://en.wikipedia.org/wiki/Moonwalk_%28dance%29 >moves backwards while seemingly walking forwards It's actually a near-perfect analogy here, where actions speak louder than words re: Microsoft's commitment to maintaining adaptations of existing open source projects. I think the example provided is enough to trigger a careful analysis before jumping in, and I would love to see counter-examples to help balance the evaluation. (Please note: very specifically requesting counter-examples of Microsoft-official, intended for production, open source repositories demonstrating long-term maintenance of tweaks of/dependencies on established open source projects that for whatever reason were never up-streamed.)
- drderidder 9y agoThis looks great, but it's important to bear in mind the architecture you intend to run on. I recently made an application blazingly fast by - among other things - parallelization using the node cluster module. On my 4-core laptop it flies. Imagine my surprise when I deployed to the cloud environment and found the typical virtual server in our cluster has only a single CPU core. The worker threads just sit around waiting for their turn to run, one at a time. On the other hand, the platform for serverless functions has 8 cores. At a minumum, before you jump into multi-threading, know what `require('os').cpus()` tells you on your target platform.
- santoriv 9y agoWhich platform for serverless functions has 8 cores? I have a CPU intensive data deployment script (Node.js) that takes 12 hours on a single thread but can be chopped up to take advantage of more cores. Our build server on ec2 has 2 cores so it's about 6 hours. It would be great to know if we could push the job into serverless and get it done a lot faster.
- drderidder 9y agoTime limits on serverless functions are 9 minutes on GCE and even less on AWS, so for long-running stateful tasks they're probably not suitable, unless you can divide the work into serial as well as parallel subsets.
- santoriv 9y agoThanks for the reply. The task is not stateful. It's just pulling data from a db, performing some transforms, and then pushing it into elasticsearch. I suppose that I could slice the tasks up to be arbitrarily small though having a longer window would be helpful. I guess I will take a look at GCE. Thank you!
- WaxProlix 9y agoFWIW I think Azure's Functions are 10 minutes and I hear they're talking about upping it again.
- drinchev 9y agoOne of the great practical examples of this repository is to serve as a counter-argument against people, who complain that NodeJS is not multi-threaded. For anything else, IMHO the use-case will be so narrow, that I wonder how MS will justify the development resources for maintaining it.
- amelius 9y agoNice, but: 1. It is exposed as a nodejs module, but some other modules may be at conflict because they may wrongly assume that they are the only thread running. E.g., some modules may be using global variables in C++. 2. Still, it doesn't support fast immutable communication (structural sharing) to other threads through shared memory.
- MuffinFlavored 9y agoWhat would it take to get number two to become a reality? Some sort of special module? This is the one main drawback I've found doing "production stuff" with Node. Does Java offer cross-thread shared memory? Go, Haskell, Python, etc.?
- cjalmeida 9y agoJava does shared memory by default and even has concurrency related concepts as fundamentals of the language (Object.wait(), etc.) . Python supports threading but is not very useful due to the infamous GIL. However, multiprocessing is usually a decent alternative and it supports shared memory on forking (copy on write, though). Also you can use mmap easily for IPC.
- k__ 9y agoHow does it compare the (discontinued) JXCore?
- daiyip 9y agoJXCore is based on node codebase, while Napa.js is written from scratch with multi-threading consideration at its core. We evaluated JXCore before starting Napa.js, but found easier to re-architecture to get performance and memory sharing right.
- nathan_long 9y agoAn alternative approach to concurrency is the one that Erlang (and your operating system) take: memory-isolated processes, preemptively multi-tasked, where neither IO nor computation in one process can adversely affect the others because the scheduler prevents it. I wrote this up: https://news.ycombinator.com/item?id=15499629 https://news.ycombinator.com/item?id=15499629
- underwater 9y agoRyan Dahl wanted Node apps to use a multi-process model. Hence the name. The vision wasn’t as evolved as Erlang, but conceptually closer than what Node looks like today. “I believe this to be a basis for designing very large distributed programs. The “nodes” need to be organized: given a communication protocol, told how to connect to each other.” ttps://www.americaninno.com/boston/node-js-interview-4-questions-with-creator-ryan-dahl/
- 0xADADA 9y agoI dont think JavaScript needs threads.
- ojosilva 9y agoI on the other hand think JS does need threads, but they should, to a certain extent, be automatically managed by the event loop and transparent to the programmer. That way you get more bandwidth (workers in fact) to process your internal JS event queue. Threads are great also when you need to do CPU intensive calculations such as processing an audio file or number crunching. That's what NapaJS seems to be geared towards in fact.
- cookiecaper 9y agoWe should be careful not to be too dismissive. In my opinion, dismissive attitudes have hurt Python considerably in the last 10 years. As people pushed the limits of Python's performance and were only met with answers like "use C for fast code, the GIL is probably never going to be removed", Go and Swift emerged, clearly intending to provide a Python-like development experience with performance characteristics more similar to Java, including the ability to run real threads. Other runtime developers should pay attention and be careful not to fall into the same trap.
- speedplane 9y ago> I dont think JavaScript needs threads. Seriously... when publishing a project like this, the authors ought to give a least a bit of insight into their motivation. Their examples include calculating Fibonocci in parallel, not exactly breakthrough.
- always_good 9y agoI know it's addicting to be dismissive, but: https://github.com/Microsoft/napajs/wiki/Why-Napa.js https://github.com/Microsoft/napajs/wiki/Why-Napa.js
- bsimpson 9y agoI know that the history of projects at a giant company isn't always straightforward, but it's interesting that they chose V8, even though Chakra is maintained by the same company (and supports Node APIs).
- daiyip 9y agoHere is why napajs is started: https://github.com/Microsoft/napajs/wiki/Why-Napa.js https://github.com/Microsoft/napajs/wiki/Why-Napa.js
- romanovcode 9y agoThis is good however IMO if you need parallelism you should not use node period.
- jonkirkman 9y agoThis looks very similar to the concurrency and isolation patterns of the Dart VM. "Use Isolates for secure, concurrent apps. Spawn an isolate to run Dart functions and libraries in an isolated heap, and take advantage of multiple CPU cores." -- https://dart-lang.github.io/server/server.html https://dart-lang.github.io/server/server.html
- Magical 9y agoWhat does this give you over using fork in node? The zone concept seems nice but I'm not understanding why I would use napa when node is designed to easily spawn nodes of parallel execution?
- christophilus 9y agoIf I understand correctly, it looks like it allows some basic sharing of data without duplicating it in a bunch of heaps. It's not 100% shared memory, in that if several threads are accessing an object, that object will be duplicated in each thread, but it has a store mechanism which essentially can serve as an in-process cache that is shared across multiple threads.
- daiyip 9y agoThat's correct. Think about a scenario that each worker needs to access a 1GB hash map. In node cluster, we have to load this 1GB map per process, but in the same process, all JS threads can access the map via an addon.
- pantalaimon 9y agoIt makes you wonder why they choose V8 instead of their own JavaScript engine https://github.com/Microsoft/ChakraCore https://github.com/Microsoft/ChakraCore
- johnhattan 9y agoMy personal theory is that they're trying to improve the JS engine in Electron so they can improve VSCode. The VSCode people have posted some performance complaints in the past. I would assume this would benefit desktop JS most, so it'd undoubtedly help Electron apps. EDIT : There's a better explanation at https://github.com/Microsoft/napajs/wiki/Why-Napa.js https://github.com/Microsoft/napajs/wiki/Why-Napa.js
- partycoder 9y agoOne of the reasons npm modules are largely compatible with each other is the fact that they share the same threading model, which is what the event loop offers. Then, this has a lot of compatibility issues, and release-wise it will be hell. I don't think this is a good idea.
- dheera 9y agoCan we please stop calling things ".js" if they are not actually JavaScript files or libraries written in JavaScript meant for direct inclusion in JavaScript source? Call it NapaJS, not Napa.js.