Is Node.js a cancer? No!! It's quite nice, really

By: (plus.google.com) +David Herron; Date: 2011-10-02 18:24

Tags: Node.JS » Event Driven Asynchronous

A recent blog post by Ted Dziuba claims that Node.js "is a cancer" and fills out a few hundred words of inflammatory laden "proof" to make his point. The post makes a few good points but is largely off base. Perhaps the most sticking point is that CPU intensive tasks make Node servers become unresponsive, but I have a clever answer for him. Another issue he raises ("JavaScript sux") is, well, as a longtime Java programmer who used to work in the Java SE team at Sun, I've had my own moments like that, but really JavaScript is quite a nice language especially if you stick to the good bits of JavaScript.

What I want to do is look past the inflamatory verbiage, and discuss the points he makes.

Is Node a non-blocking system?  Sheesh, how overly pedantic of him.  The Node team wants us to think of Node as a nonblocking system, but Dziuba wants to get all pedantic on us about the definition of a blocking function call.  Okay, fine, whatever, but does it make a difference that technically every function call that returns a value is a blocking function?  So f'ing what?  Let's be more pragmatic, as Ryan Dahl is.  It's clear from the presentations he's made, the posts on his livejournal blog (from the period in which he was designing Node), etc, that he's got a more pragmatic definition of "blocking".  That he wants us to think about functions that take a "long" time to run, versus ones that take a "short" time to run.

If you were to, like I've done, read through Ryan Dahl's livejournal blog you see that his design goals were to distinguish between long and short time length function calls. He wasn't being pedantic about the exact meaning of blocking functions, and neither should we.  Further - the same sort of issue is at play in GUI programming where in most GUI toolkits event dispatch happens on an event dispatch thread, and if the event dispatch thread gets hung up with CPU intensive computation the GUI application can appear sluggish.  Just as there's a rule of thumb in GUI programming that event handlers must return quickly, so too is there a similar rule in Node programming, for the same reason.

Not everything can be packaged into neat non-blockin asynchronocity? As Dzuiba points out it's easy to accidentally develop functions that take a long time to compute given the right input.  His example, the Fibonacci sequence, is one.  In my book, (www.amazon.com) Node Web Development, I used an extremely similar Fibonacci function to go over the same territory of long-running CPU bound algorithms that block the event dispatch loop.

But rather than spend a couple hundreds of bitchy flammage using this example to say how horrible Node is (like Dziuba did), I showed my readers a couple smart strategies.  The basic strategic moves you can make to handle compute intensive stuff is:-

  • Rewrite the algorithm to be more efficient
  • Convert the algorithm to an asynchronous one
  • Host the algorithm on a back-end compute server

In my book I did the second two of those.  I rewrote the simplistic the simplistic Fibonacci algorithm into one that's just as simplistic, but behaves asynchronously, and dispatches it's work through the Node event queue.  It didn't take very long to develop the asynchronous Fibonacci, and it works fairly well in Node.  In other words, for some algorithms in some circumstances you'll be able to refactor to dispatch work across the event queue and not block the server.

The book also demonstrated how easy it is to implement a simple REST service in Node for requesting Fibonacci values.  Because Fibonacci is deterministic, I'd think a Fibonacci service behind a caching proxy server would be an excellent optimization.  In any case REST services are a normal best practice to distributing work, and it seems that farming CPU intensive work to a back-end server is an obvious strategy to employ.

Don't get hung up on the Fibonacci algorithm itself - but look at it as an example.

Does Node disobey "the Unix way"? Sheesh. In the old days CGI was developed as a stopgap way to connect software to the Apache web server to implement dynamic page generation. It was a big step forward in 1995 but to hold that up as the epitome of web app development in 2011 is, well, lunacy. I'm trying to stay civil, but really!

Node by itself is kind of like a Lego kit of all the building block fundamentals from which you'd build a wide variety of things.  It doesn't correspond to Apache or Nginx .. it corresponds to C and the standard C library, meaning that it has the building blocks from which you'd build a full web server or anything else.

Rather than base your separation of responsibility on forking a new process for every incoming request (CGI is based on forking processes) why not separate your responsibility into multiple tiers with REST/etc services to talk to back ends.  Doesn't that sound modern?  Yeah, it does.  And Node makes it way simple easy to develop REST services.  So simple that it took 2 pages or so in my book to go over developing REST server and client implementations of the Fibonacci algorithm mentioned above.

It's dangerous that Node programmers have the full power to implement a web server from scratch! Uh... This is one of the most powerful and fun parts of Node to work with, and he wants to make it a hindrance?  Let's ponder for a second to another popular language for web app development: Java.  Java programmers also have all the API's in their hands with which to write web servers from the metal up, but they rarely do. Instead there are several application frameworks for Java that people use to write their web apps, and the app framework or the app server takes care of the web server part.

In my book I argue that Node programmers should do the same. There are a lot of details to get right in developing a proper web server, because there are several protocols to get right. It would be better to leave the details to a framework author who can take the time to learn the protocols and implement them correctly.

JavaScript is a horrible evil language? Earlier I mentioned that I'd worked in the Java SE team at Sun. For 10ish years, in fact.  The war over dynamic loosely typed languages versus strictly typed languages was hot and heavy during my time there, with people turning their attention to Python or Ruby on Rails, and saying that Java Is Dead because the dynamic loosely typed languages are more productive.  I wrote many blog posts during that time extolling the virtues of Java as a strictly typed language that helped programmers by insisting on strict type checking giving some assurances that a large class of errors cannot happen in Java, but are likely to happen in loosely typed dynamic languages because of their lack of type checking.

I've learned since "leaving" Sun that there is a lot of programmers who despise Java and it's strict type checking.  They think of Java as an evil horrible language, and love JavaScript instead.

In other words - each person has their preferences.   JavaScript is a nice and quite powerful language. Well, as long as you steer clear of the bad parts (as with any language).

Maybe someone pissed in Dziuba's wheeties after he got up on the wrong side of the bed, and that we should take his raining upon Node's parade with a grain of salt.  Maybe.  In the meantime Node is nowhere near as bad as he made it out to be.  It's not the solution to every problem, and we shouldn't delude ourselves into thinking that it is.  At the same time it isn't a horrible piece of garbage, instead it's quite useful and powerful.

« Ryan Dahl: History of Node.js Ryan Dahl: Introduction to Node.js Ryan Dahl's presentation at Yahoo »