The general message of the presentation was that threads suck and asynchronous programing is the king. Come again? I don't quite agree with that (or rather agreed, as you'll see in brief) - wasn't that for the threads to save us from the onerous asynchrounous programming with its context information and callbacks (remember Windows event programming?)! The threads justly delivered a convenient abstraction to group the logically connected data and logic in separate units of execution. So now we are doing a full circle: from asynchronous to threads to asynchronous?
OK, on the surface that may be looking like that, but there's more to that. The problem is that when we apply threads to parallel I/O they are just to slow (you know, context switching, thread stampedes and all that). Thus there's a host of asynchronous I/O methods starting with the venerable select() UNIX call. Ok, agreed, for that special field the threading model isn't very appealing, but for the general usage I'd just hide this inside of an I/O thread...
Now there's this pesentation (Ryan Dahl’s talk on Node.js) and what the author says is exactly that: callbacks and asynchronicity are good! How that? We all know it's a pain in practice? His response (an this is the valuable insight got when watching this) is that we just didn't have a good enough programming language to realise that! When you do in in C (as you'd likely to do when programming performant I/O) you are messed up, but if you take Javascript...
See, that's the crux here: Javascript was designed to work in a callback driven environment, so the language has unique mechanisms which no other language can offer. Thus if we take Javascript and do event oriented programming it's a breeze then! The idea is to take the ultra higspeed C library (libev in that case) and wrap it with event-friendly Javascript hull. Here's an example code from node.js site:
var net = require('net');
net.createServer(function (socket) {
socket.setEncoding("utf8");
socket.addListener("connect", function () {
socket.write("Echo server\r\n");
});
socket.addListener("data", function (data) {
socket.write(data);
});
socket.addListener("end", function () {
socket.end();
});
}).listen(8124, "127.0.0.1");
Well, maybe it isn't a thing of beauty (if you're not into Javascript) but it's concise, everything is at one place, and you can read it without reading tons of manuals first. So maybe this is the way of doing this? Another thing I liked that node.js never provides a blocking API - even filesystem calls are asynchronous! That's consequence!
Sorry for the short post, but it's summer, I want to go out and watch some worldcup!
---
Resources:
1. the talk to be found here: http://jsconf.eu/2009/video_nodejs_by_ryan_dahl.html
2. and here's the code: https://gist.github.com/a3d0bbbff196af633995
3. if you'd like some more technical details, here's an excellent post by Simon Wilson: http://simonwillison.net/2009/Nov/23/node/
4. node.js critique (yes, there's such a thing too!): http://al3x.net/2010/07/27/node.html
Addendum:
- here is a simple blog engine in less than 200 lines of code using node.js : http://github.com/zefhemel/persistencejs/blob/master/test/node-blog.js. Not bad, I'd say.
- Multi-node: how to implement a concurrent node.js HTTP server: http://www.sitepen.com/blog/2010/07/14/multi-node-concurrent-nodejs-http-server/
- Hummingbird: an impressive application based on node.js - http://mnutt.github.com/hummingbird/
Late to the party?
ReplyDeleteLate to the party?
ReplyDeletelibev actually not libevent
ReplyDelete@MrApples
ReplyDeleteYou missed the point, it's not node.js that's new, it's the new angle on the problem I obtained.
@Anonymous
ReplyDeleteYou're of course right, I didn't proofread correctly :-(. So it was:
1. libev event loop library (Marc Lehmann)
2. libeio thread pool library (Marc Lehmann)
JavaScript may be well suited but doesn't offer anything unique that is required for working in a callback environment. Scheme had it all.
ReplyDelete@Ted Henry
ReplyDeleteI do not know Scheme, so I cannot judge it, but I don't understand your comment wholly: Javascript is as much of functional as you could get until recently, and thus can install functions defined on the fly as callbacks. That's a spot of support for callbacks...
On the other side I can somehow understand your intend, look for example at comaprison of Node.js with a fresh Clojure library aleph ("Clojure's edge on Node.js" - http://dosync.posterous.com/22397098). For my eyes the Clojure code snippet there is clearer and more readable!
But once more, if you're not a functional programmer, than Javascript should be good enough here...