Lessons from Node.js

Node.js is a server-side Javascript library for writing scalable network servers. It’s primary purpose is to wrap an asynchronous library around synchronous low-level calls. Code written to block on IO wastes time waiting for a response.

var response = synchCall(parameters) ;
useResponse(response);

The only way to get work done with this code is to have another thread ready to run. Apparently, Apache handles this by creating a new thread per connection, which can be very expensive. Each thread takes 2MB (though this can be reduced, right?) and context switching between threads is relatively expensive. So it doesn’t appear to scale very well, although, this is the worst possible implementation and can be improved with threadpools and/or green threads. An alternative it to switch to asynchronous calls.

asynchCall(parameters,
           function(response) { useResponse(response); }
          );

The callback is stored somewhere, ready to execute whenever the asynchCall returns. This requires that every blocking call be rewritten in this asynch style. To me, this looks like continuation-passing style (CPS), which is a transformation performed automatically by many Scheme compilers. The callback technique here has to be used carefully, i.e. not recursively, to avoid blowing the stack. With continuations you could use this style and not use a single excess stack frame. It would just quickly jump directly into each callback.

It would be interesting to see if a Scheme runtime can be written such that all IO continuations are implicitly asynchronous. I think you’ll need a parallel let to start multiple events; otherwise, it’s still just a single-threaded program. Maybe the signature of these IO functions would something like “read (kontinuation, koncurrent)”. The first continuation is registered to execute when the read finally gets a character from IO. The second continuation is executed immediately as a separate “green thread” of execution. Maybe I can integrate the C wrapper library written for Node.js into a Scheme interpreter like Scheme48. Then I can use scsh, the Scheme shell, to write scripts for scalable servers. I’ll have to think about the semantics of that parallel let thingie though.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s