Comment by revorad
14 years ago
If possible, can someone ignore the showers of vitriol for a minute, and comment on the technical merit of his criticism of Node? I ask because I'm a total noob and would like to understand what's being discussed.
14 years ago
If possible, can someone ignore the showers of vitriol for a minute, and comment on the technical merit of his criticism of Node? I ask because I'm a total noob and would like to understand what's being discussed.
comment on the technical merit
Hi, Hrishi. There is a grain of technical merit in two of his three objections, but he trollishly overstates them. I've had to think about some of the same questions lately, so here are some thoughts. If anyone has a substantially different perspective, I'd like to hear it.
By the way, the most interesting thing about his critique is that he doesn't even touch on the most common objection to Node, that async callbacks don't compose well and so break down under complexity. That one's been argued to death on HN, though, so I'll follow his example and leave it out of this.
Let's consider the criticisms in reverse order. #3, about Javascript, we can dismiss as a vacuous language flame. #2 is about separation of concerns. He argues that web servers should be separate from web apps, and Node confuses the two by doing web server stuff (handling HTTP requests) and app stuff (whatever your app does) in the same context. Now you either have to put a "real" web server in front of Node (in which case there's the question of what value Node's adding) or use a relatively immature web server (Node itself) as your front end. There is a good point about modularity here. But is the line between web servers and web apps always so clear-cut? If his argument were completely true, CGI would be perfect for everything. Most people wouldn't agree with that. Moreover, you wouldn't see complex configuration languages and extension APIs for web servers, the kinds of things that arise when the lines start to blur (and are not very pleasant to work with). So the question is just how separate the concerns really are. This surely depends on the application. Separation of concerns is a good thing until interactions between modules become unduly complex, at which point one sometimes gets a big simplification by unifying them.
For example, in the project I'm working on, there are resources that need to be requested by the browser and sometimes also by the (app) server in order to complete some computation. You could divide this work many different ways, but it sure is convenient to just write Node handlers to do whatever I/O you need in the course of completing a request. To have the app server go back to the web server would be awkward, and so would having two different ways of fetching the same stuff.
#1 is about blocking. He refutes a blurb that says "nothing blocks in Node" by showing a trivial example that indeed does block Node by doing a long computation in an event handler. (One wonders why he didn't go full retard and just put an infinite loop in there.) This is a deliberate misreading of the blurb, which obviously meant not "nothing blocks" but "no I/O blocks". So, a straw man. But dig deeper and there is a valid point nearby. If you have long computations to do while fulfilling a request (where "long" is defined as "taking longer than you're comfortable having all other requests to this server wait"), then for Node to work well, you have to farm those computations out to other processes. This is doable, but adds complexity. You start to move out of Node's sweet spot.
What's the sweet spot? If writing your server code in Javascript is a win for you and your app is I/O bound (more precisely, if there aren't any long-running computations as defined above), Node looks pretty good. If in addition the app server and web server have more complex interactions than just "here's your request" and "here's your reply", it starts to look really good. An example might be a web chat app.
As things get more complex, the judgments get trickier. In our case, we do have long-running computations. Bad for Node. But we also have webserver-like needs in our appserver, a lot of I/O that we don't want to block on, and Javascript is a big win for us. So on the whole Node wins. Take away the point about Javascript, though, and it probably wouldn't.
My take is that the post is more a matter of philosophy than technical merit.
Just think about this:
A poorly designed application will perform badly on any framework. While many programmers understand more sequential application bottlenecks, event driven bottlenecks can be hard to understand for "less expert programmers".
Ted thinks Node.js doesn't adequately inform new developers of its pitfalls, and it is developing a "Node.js makes everything faster" mentality.
Just take time to do things correctly and Node.js (like any other tool) can be a great design decision. Just understand that you need to write good code to get the promised performance improvements.
Additionally, proxying behind nginx or some other server is a good idea.
Non-blocking architecture is not the be all/end all solution for performance problems. By calculating large fibonacci numbers (pounding the CPU), he causes node to fall apart. Basically, there is no such thing as easy scaling, and any solution advertising such is lying.
He found the one thing JS is terrible at - heavy math - and thought of a way to make Node look as bad as possible based on it. He should not be listened to.