This is exactly where I want to go with RingoJS: Many threads with private mutable scope, global read-only scope, worker/actor based thread interop, one event loop per thread.
Currently we still have shared mutable state that sometimes requires locking (unless you resort to a functional style of programming): http://hns.github.com/2011/05/12/threads.html
I think the opinions expressed in this article are valid.
However, I don't think the inability of current JavaScript to do async I/O without callbacks is Node's biggest problem. As others have said, it works for smaller projects (and even has some geek appeal). And as Havoc Pennington and Dave Herman have explained, generators (which are coming with ECMAScript Harmony) and promises will eventually provide a very nice solution. So Node has a path to grow out of the callback model without giving up its single threaded paradigm.
The bigger problem (which I don't see getting solved anywhere down the road) is the lack of preemptive scheduling, which is available in Erlang or on the JVM. What you see under high load with Node is that latency is spread almost linearly over a very wide spectrum, from very fast to very slow, whereas response times on a preemptively scheduled platform are much more uniform.
And no, this is something that can't be solved by distributing load over multiple CPU cores. This is problem really manifests itself within each core, and it is a direct consequence of Node's single threaded execution model. If anybody knows how to solve this without resorting to some kind of preemptive threading I'd be very curious to hear about it.
The only way to make it expand forever would be to support recursion. Would be interesting what texts you could come up with that. Kind of a textual Mandelbrot set.
Yes, --trace-gc shows about 10 Mark-sweeps per second, each taking around 13 ms (no compacts though as far as I could see). But are those ~15% spent in GC are enough to explain the performance?
You are right about the title. That "not ready for the server" is a foolish phrase. I'd change it to "not tuned for the server" if I could, but it looks like it's impossible to change that now.
Just an educated guess. If you're allocating tons of objects and strings and your app gets slow, it's very likely to be the GC. But I don't know V8 well enough to say for sure.
The JSON I'm parsing is just objects with short string properties (around 10 characters). There's just one longer 25kb JSON string but that is never collected. As to Node configuration, can you provide some specific options to use? I've been asking about this on #node.js (and ryan) and I'm open to any suggestions.
Ringo is running with the server hotspot JVM without any further options.
I'm the author of both the original article and this HN posting - and yes, I am biased, since I'm the main developer of RingoJS (the other platform in that benchmark). I've made that quite clear and provided additional background in the original benchmark to which this is just a short update: http://hns.github.com/2010/09/21/benchmark.html
I think my benchmark and the conclusions I draw from it (after a lot of thinking) are fair. My intention is just to make people see there's no magic bullet with performance or scalability, and that there are alternatives for server-side JavaScript.
I submitted a Ringo talk to JSConf.eu 2010, haven't heard anything back from these guys so far. If that fails, I may apply for next JSConf.us. We'll get the word out there eventually :)
I think Netty is great if you want fine grained control over each aspect of your network stack and/or ultimate performance. But having a full featured web server that does sync and async equally well is a value that shouldn't be dismissed either.
Comparing comet performance between node and ringo should be interesting. Ringo uses jetty/cometd, so it should scale pretty decently as well. My guess is that node will use less memory per connection (and thus allow more simultanous connections), while ringo/jetty should have better latency. This is also what this benchmark suggests: http://praxx.is/post/486034949/comet-with-bayeux-node-js-vs-...
Currently we still have shared mutable state that sometimes requires locking (unless you resort to a functional style of programming): http://hns.github.com/2011/05/12/threads.html