News for hackers. Stuff that matters.
Re:Hard-won lessons: Five years with Node.js by ralusek on Wednesday April 19, 2017 @11:37PM (#14153730)
NodeJS has a handful of things that tend to get brought up. Callback soup and difficult error handling. Both are resolved by promises. Once you get the hang of promises, you are capable of doing concurrent asynchronous tasks in a manner that would be significantly more difficult in any other language.

On top of that, NodeJS is very, very fast. Compared to Python or Ruby, straight computing is significantly faster, but that's not even where the meaningful gains come from. Because NodeJS is non-blocking, the core is IMMEDIATELY available to serve the next request once an asynchronous call is made (read from DB/Cache/HTTP call). Because of this, each core can serve thousands of simultaneous connections.

Because JS is single threaded, in order to take advantage of multi core hardware, you just run the cluster module to effectively launch a concurrent instance of your application for each core.

As far as the language itself, once I understood it, I loved it. At first, I thought it was terrible, but when I went to ES6 syntax, and fully groked how to write asynchronous code, it rocketed to my favorite language.

I started with Java, moved to Python, and although it took me a while to come around to JS, I would absolutely never go back.

Re:Hard-won lessons: Five years with Node.js by lod723 on Thursday April 20, 2017 @12:16AM (#14153908)
> Once you get the hang of promises, you are capable of doing concurrent asynchronous tasks in a manner that would be significantly more difficult in any other language.

FYI, anyone who has worked with Elixir or Erlang views these sort of statements about Node as completely ridiculous. The only languages right now that are making a serious effort to bring real concurrency to modern programming are Go and Elixir. Node with its single threadedness and global heap doesn't come close, since those are fundamental problems with JS. The papering over the defienct language concepts with attempts like promises don't address these issues at all.

Re:Hard-won lessons: Five years with Node.js by ralusek on Thursday April 20, 2017 @01:53AM (#14154283)
For concurrent asynchronous tasks, being single threaded or multithreaded shouldn't make any meaningful difference. To make a million concurrent asynchronous calls on a single thread takes couple MS, to make on multiple threads takes about the same. For concurrent SYNCHRONOUS tasks, being single threaded or multithreaded makes a huge difference, but that's not what we're talking about here. It's also not at all fair to call NodeJS single-threaded in regards to its concurrency model, as it utilizes all cores through parallel application instances.
Re:Hard-won lessons: Five years with Node.js by lod723 on Thursday April 20, 2017 @02:40AM (#14154458)
The multiprocess Node concurrency model is brittle and fault intolerant. The event loop scan actually has real bottlenecks at a certain level of fds in flight. A real scheduler really wins here; libuv sits below the knowledge of the runtime to really be optimal. You become CPU bound far sooner than you expect.

With a global heap, you also become memory bound far sooner than you expect as well.

Re:Hard-won lessons: Five years with Node.js by chrisco255 on Thursday April 20, 2017 @03:47AM (#14154720)
Your typical Node instance is using an order of magnitude less memory than the beastly JVM. We use Java microservices with Spring at my job and each "micro" service consumes close to 1GB of memory. I've never written a Node service that had more than 100MB footprint.
Re:Hard-won lessons: Five years with Node.js by empthought on Thursday April 20, 2017 @07:53AM (#14155822)
The default maximum heap size for the JVM on systems with 4GB or more of RAM is one gigabyte. Has this been changed in your microservices' startup parameters? If not, it is no surprise that Java uses the memory that you have allocated to it before garbage collecting.

Spring Boot microservices that don't do much shouldn't need more than 32MB heap -- see https://spring.io/blog/2015/12/10/spring-boot-memory-perform... for details.

Re:Hard-won lessons: Five years with Node.js by lod723 on Wednesday April 26, 2017 @10:57AM (#14203505)
The JVM has the same global heap problem as Node... it's frustrating that with all the development that goes into the JVM this problem remains unaddressed.
Re:Hard-won lessons: Five years with Node.js by Can_Not on Saturday April 22, 2017 @02:53PM (#14174073)
When they say node has great ease of asynchronous non blocking IO, they are certainly not talking about vs golang or erlang. As much as the concurrency is fake, as long as _real concurrency_ is not a fundamental business requirement, it's way better than literally no concurrency.
Re:Hard-won lessons: Five years with Node.js by goatlover on Thursday April 20, 2017 @02:07AM (#14154336)
Julia's support for concurrency is right there with Go and Elixir.
Re:Hard-won lessons: Five years with Node.js by lod723 on Thursday April 20, 2017 @02:42AM (#14154464)
Will take a look! There really should be more ecosystems that try to solve modern problems effectively.
Re:Hard-won lessons: Five years with Node.js by dragonwriter on Thursday April 20, 2017 @01:01AM (#14154085)
> Once you get the hang of promises, you are capable of doing concurrent asynchronous tasks in a manner that would be significantly more difficult in any other language.

Of the top of my head, concurrent asynchronous tasks are simpler in Pony, Go, Erlang, Elixir, Haskell, and Oz than in JS (and these generally also handle parallelism beyond "run another instance of your app", too); and lots of other languages have concurrency constructs equivalent to JS promises (and, often, also async/await), so JS is at best no easier than that larger group.

Re:Hard-won lessons: Five years with Node.js by Jean-Philipe on Thursday April 20, 2017 @12:23AM (#14153946)
> you are capable of doing concurrent asynchronous tasks in a manner that would be significantly more difficult in any other language.

"any other language" is a bold claim. I heard Haskell gets concurrency more elegantly, or Erlang.

Re:Hard-won lessons: Five years with Node.js by jcrites on Thursday April 20, 2017 @12:11AM (#14153879)
> Once you get the hang of promises, you are capable of doing concurrent asynchronous tasks in a manner that would be significantly more difficult in any other language.

What languages are you comparing against? It seems like asynchronous code is more difficult to write in NodeJS than in C#, Go, or Rust, and about the same as Java. I can write code in Java in a style similar to promises using ListenableFuture (Google Guava) or CompletableFuture (Java 8) [0].

I should also clarify that I don't think promises are the optimal approach to asynchronous code. I think you can do better, and the primitive "await" is an example of how. Bob Nystrom (munificient) wrote an article called "What Color is your Function?" [1] that does a good job describing the difficulties of promised-based async, and how await improves on it, and how Go does even better.

(From what I've read, JavaScript ES8 is supposed to include async/await, and NodeJS seems to have support for them. At that point you'll be able to program in standard JavaScript and use await, which will bring NodeJS up to parity with the first-tier languages.)

> On top of that, NodeJS is very, very fast. Compared to Python or Ruby,

Perhaps that's true compared to Python and Ruby, but not when compared to other high-performance runtimes like Java. The following three paragraphs are from a comment I previously wrote on this topic [2].

Folks might also be interested in the TechEmpower web framework benchmark [3]. The top Java entry ("rapidoid") is #2 on the benchmark and achieves 99.9% of the performance of the #1 entry (ulib in C++). These frameworks both achieve about 6.9 million requests per second. The top Java Netty server (widely deployed async/NIO server) is about 50% of that, while the Java Jetty server, which is regular synchronous socket code, clocks in at 10% of the best or 710,000 R/s.

NodeJS manages 320,000 R/s which is 4.6% of the best. In other words, performance-focused async Java achieves 20x, regular asynchronous Java achieves 10x, and boring old synchronous Jetty is still 2x better than NodeJS throughput. NodeJS does a pretty good job given that it's interpreted/JITed while Java is compiled, though Lua with an Nginx frontend can manage about 4x more. NodeJS is handicapped by having to orchestrate everything from its single thread.

I agree that asynchronous execution can provide an advantage, but it's not the only factor to consider while evaluating performance. If throughput is someone's goal, then NodeJS is not the best platform due to its concurrency and interpreter handicap. If you value performance then you'll chose another platform that offers magnitude better requests-per-second throughput, such as C++, Java, Rust, or Go according to [3] and [4]. But I'll grant it has better IO performance than many other dynamically typed languages.

Asynchronous execution also does not necessarily require explicit async programming. Other languages have as good or better async support -- for example, see C#'s `await` keyword. [1] explores async in JavaScript, await in C#, as well as Go, and makes the case that Go handles async most elegantly of those options. Java has Quasar, which allows you to write regular code that runs as fibers [5]. The code is completely normal blocking code, but the Quasar runtime handles running it asynchronously with high concurrency and M:N threading (similar to Go). Plus these fibers can interoperate with regular threads. Pretty gnarly stuff (but requires bytecode tampering). If async is your preference over Quasar's sync, then Akka might be up your alley instead [6].

Lastly, high performance servers don't necessarily require asynchronous code at the application layer; performance sensitive logic can often live in the library or framework e.g. Netty, reverse proxy e.g. Nginx, or in the OS's context switching.

> Because NodeJS is non-blocking, the core is IMMEDIATELY available to serve the next request once an asynchronous call is made (read from DB/Cache/HTTP call). Because of this, each core can serve thousands of simultaneous connections.

This also describes regular synchronous code with many threads. Once your application makes a blocking call, the operating system context switches to another thread (process). This is how boring old blocking Java code running on Jetty outperforms NodeJS in request-per-second benchmarks [3]. And you could take advantage of this in NodeJS too if it weren't for the fact that JavaScript execution occurs in a single thread!

For most typical applications, overall performance is more influenced by the efficiency of the runtime than it is by the concurrency/async strategy.

[0] https://github.com/google/guava/wiki/ListenableFutureExplain... and https://docs.oracle.com/javase/8/docs/api/java/util/concurre...

[1] http://journal.stuffwithstuff.com/2015/02/01/what-color-is-y...

[2] https://news.ycombinator.com/item?id=12341886

[3] https://www.techempower.com/benchmarks/#section=data-r11&hw=...

[4] https://news.ycombinator.com/item?id=12268988

[5] http://docs.paralleluniverse.co/quasar/

[6] http://akka.io/

Re:Hard-won lessons: Five years with Node.js by merkaloid on Thursday April 20, 2017 @06:03AM (#14155341)
that's a lot of text you wrote for something that will get automatically disregarded by anyone with a brain for having mentioned plaintext response benchmarks
Re:Hard-won lessons: Five years with Node.js by mlvljr on Thursday April 20, 2017 @09:47AM (#14156549)
what would be wrong with that?

secondly, what do non-plain-text benchmarks give us?

Re:Hard-won lessons: Five years with Node.js by amalantony06 on Thursday April 20, 2017 @08:38AM (#14156072)
Love this. This is precisely why I love Javascript too, I find these douchey condescending comments on Javascript/Node.js from people who've not grasped the language and it's philosophy deeply, extremely annoying.

There's a lot a capable developer can accomplish with Javascript, with it's first order functions, collection operations, generators, promises and now, async /await. Granted JS is not idiot-proof, but I'd any day use a powerful language than a highly restricting one (think Java and Go).

Re:Hard-won lessons: Five years with Node.js by lawik on Saturday April 22, 2017 @03:26AM (#14171519)
Or maybe they just don't share the philosophy. Or are opposed to it. A lot of Node enthusiasts also come across as douchey and condescending as they claim that people just haven't grasped the language or its philosophy.

I think Node is absolutely fine. But I see why someone who values robustness and error-reduction as primary goals or someone that has a firm grasp on other asynchronous models might not see many advantages to Node. Just as some people value stability higher than progress, neither is necessarily evil, just beliefs.

People have different priorities and Node delivers on some and is not geared towards others.

But I don't find Nodes async, single thread model very interesting or revolutionary. It is very pragmatic and definitely useful but I found the Erlang VM and Elixir a much more compelling solution for example.

Re:Hard-won lessons: Five years with Node.js by amalantony06 on Sunday April 23, 2017 @09:42AM (#14178122)
Hey, more power to you if you want to use more expressive/functional languages than Javascript like Erlang or Clojure. However claiming that a language that allows nothing beyond the Object oriented model of computation like Java or Go is more robust or allows you to have less errors would not be accurate (see the comments above).

The primary reason anyone would use Javscript over say Erlang would be the ubiquity of the language and the availability of libraries or strong familiarity with the language. But my point is Javascript provides you the tools to write functional code that is robust (if you are disciplined) and generators + promises (and async/await) makes the single threaded async model painless. I certainly did not claim that it was a silver bullet or a revolutionary model of computation.

Re:Hard-won lessons: Five years with Node.js by uranian on Thursday April 20, 2017 @03:26AM (#14154636)
> Once you get the hang of promises,

.then( you realize it's just a callback..

Re:Hard-won lessons: Five years with Node.js by int_19h on Thursday April 20, 2017 @01:03AM (#14154091)
What language doesn't have promises these days?