; Date: 2011-10-02 18:24
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, 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.
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.