|
|
@ -14,7 +14,7 @@ |
|
|
|
|
|
|
|
<h1><a href="http://tinyclouds.org/node">Node</a></h1> |
|
|
|
|
|
|
|
<p id="introduction">Purely evented I/O for <a |
|
|
|
<p id="introduction">Purely event-based I/O for <a |
|
|
|
href="http://code.google.com/p/v8/">V8 javascript</a>. |
|
|
|
|
|
|
|
<p>An example of a web server written with Node which responds with |
|
|
@ -39,18 +39,22 @@ Server running at http://127.0.0.1:8000/ |
|
|
|
|
|
|
|
<p> See the <a href="api.html">API documentation</a> for more examples. |
|
|
|
|
|
|
|
<p> Node's goal is to provide easy, scalable concurrency. In the above example, |
|
|
|
the 2 second delay does not prevent the server from handling new requests. |
|
|
|
|
|
|
|
Node tells the operating system (through <code>epoll</code> or |
|
|
|
<code>kqueue</code> or <code class="sh_none">/dev/poll</code> or <code>select</code>) that it |
|
|
|
should be notified when the 2 seconds are up or if a new connection is |
|
|
|
made—then it goes to sleep. If someone new connects, then it executes |
|
|
|
the callback, if the timeout expires, it executes the inner callback. |
|
|
|
Each connection is only a small heap allocation. |
|
|
|
|
|
|
|
<p>This is in contrast to most scripting languages where OS threads are employed for |
|
|
|
concurrency. But thread-based networking |
|
|
|
<p> Node's goal is to provide an easy way to build scalable network |
|
|
|
programs. |
|
|
|
In the above example, the 2 second delay does not prevent the server from |
|
|
|
handling new requests. |
|
|
|
Node tells the operating system (through |
|
|
|
<code>epoll</code>, |
|
|
|
<code>kqueue</code>, |
|
|
|
<code class="sh_none">/dev/poll</code>, |
|
|
|
or <code>select</code>) |
|
|
|
that it should be notified when the 2 seconds are up or if a new connection |
|
|
|
is made—then it goes to sleep. If someone new connects, then it |
|
|
|
executes the callback, if the timeout expires, it executes the inner |
|
|
|
callback. Each connection is only a small heap allocation. |
|
|
|
|
|
|
|
<p>This is in contrast to today's more common model |
|
|
|
where OS threads are employed for concurrency. But thread-based networking |
|
|
|
<a href="http://www.sics.se/~joe/apachevsyaws.html">is</a> |
|
|
|
<a href="http://www.kegel.com/c10k.html">relatively</a> |
|
|
|
<a href="http://bulk.fefe.de/scalable-networking.pdf">inefficient</a> |
|
|
@ -60,55 +64,46 @@ very |
|
|
|
difficult |
|
|
|
to |
|
|
|
use. |
|
|
|
|
|
|
|
<p> |
|
|
|
Node will show much better memory efficency under high-loads |
|
|
|
<!-- TODO benchmark --> |
|
|
|
than other systems |
|
|
|
which allocate 2mb thread stacks for each connection. |
|
|
|
than systems which allocate 2mb thread stacks for each connection. |
|
|
|
|
|
|
|
<p>Users of Node are free from worries of dead-locking the |
|
|
|
process—there are no locks. In fact, there arn't even blocking |
|
|
|
functions. Because nothing blocks, Node can be given to less-than-export |
|
|
|
programmers to build servers. |
|
|
|
|
|
|
|
Node is similar to systems like |
|
|
|
<p>Node is similar to systems like |
|
|
|
Ruby's <a href="http://rubyeventmachine.com/">Event Machine</a> |
|
|
|
or |
|
|
|
Python's <a href="http://twistedmatrix.com/">Twisted</a>. |
|
|
|
But Node also provides full access to the file system in a non-blocking way. |
|
|
|
(This is done by using an internal thread pool to handle file system calls.) |
|
|
|
Because Javascript does not have I/O libraries and because <i>nothing</i> in |
|
|
|
Node blocks, a Node programmer is going to find it difficult to write slow |
|
|
|
servers—even if they don't understand how the concurrency system |
|
|
|
works. |
|
|
|
|
|
|
|
<p>Notice in the above example the <code>puts()</code> call is made |
|
|
|
immediately. |
|
|
|
|
|
|
|
<p>Node's HTTP API has grown out of my difficulties while developing for |
|
|
|
Merb and Ebb. Because of limiting low-level design choices, streaming data |
|
|
|
through Rack-based frameworks is difficult or impossible. Streaming is |
|
|
|
important for large requests or responses (uploads or downloads), so that |
|
|
|
the data is not buffered in memory. Other small problems, the incorrect |
|
|
|
assumption that all message headers have unique fields are dealt with. The |
|
|
|
result is a fast, scalable, and complete low-level HTTP API which can be |
|
|
|
built upon. |
|
|
|
|
|
|
|
<p> Evented program is different. It requires the program to change how they |
|
|
|
view the problem. But it provides many benefits and it more closely matches |
|
|
|
what the machine is actually doing. In someways threaded programming is like |
|
|
|
fitting a square block into a round hole, and all of the deadlocks and |
|
|
|
memory inefficiencies that come from that are a result of the struggle. |
|
|
|
Javascript, thankfully, has no concept of threads |
|
|
|
<a |
|
|
|
href="http://weblogs.mozillazine.org/roadmap/archives/2007/02/threads_suck.html" |
|
|
|
>and never will</a>. It has a very lucid closures and anonymous functions, |
|
|
|
which make evented programming tolerable. |
|
|
|
|
|
|
|
<p> "But what about multiple-processor concurrency?", you ask. "Threads are |
|
|
|
necessary to scale programs to multi-core computers." The name <i>Node</i> |
|
|
|
should give some hint at how it is envisioned being used. Processes are |
|
|
|
necessary to scale to multi-core computers, not memory-sharing threads. The |
|
|
|
But Node takes the paradigm. |
|
|
|
In other systems, there is always a blocking call to start the event-loop. |
|
|
|
Typically one sets up behavior through callbacks and at the end starts the |
|
|
|
server through a call like <code>EventMachine::run()</code>. In Node, |
|
|
|
there is no such thing. By default Node enters the event loop after |
|
|
|
executing the input script. Node exits the event loop when there are no more |
|
|
|
callbacks to perform. |
|
|
|
|
|
|
|
<p>Node's HTTP server has grown out of my difficulties developing |
|
|
|
and working with web servers. For example, streaming data through most web |
|
|
|
frameworks is difficult or impossible. Or like the oft-made false |
|
|
|
assumption that all message headers have unique fields. Node attempts to |
|
|
|
correct these problems by providing a low-level but complete HTTP API. |
|
|
|
Coupled with Node's purely evented infrastructure, it will make a solid foundation for |
|
|
|
future frameworks. |
|
|
|
|
|
|
|
<p> <i>But what about multiple-processor concurrency? Threads are necessary |
|
|
|
to scale programs to multi-core computers.</i> The name <i>Node</i> should |
|
|
|
give some hint at how it is envisioned being used. Processes are necessary |
|
|
|
to scale to multi-core computers, not memory-sharing threads. The |
|
|
|
fundamentals of scalable systems are fast networking and non-blocking |
|
|
|
design—the rest is message passing. In the future, I'd like Node to |
|
|
|
be able to spawn new processes, have a library for passing JSON messages, |
|
|
|
and be able accept connections from multiple processes (a pre-fork server); |
|
|
|
but these are things that fit into the current design and do not require |
|
|
|
threads. |
|
|
|
to be able to spawn new processes (probably using the <a |
|
|
|
href="http://www.whatwg.org/specs/web-workers/current-work/">Web Workers |
|
|
|
API</a>), but this is something that fits well into the current design. |
|
|
|
|
|
|
|
<p> Node is released under an MIT license.</p> |
|
|
|
|
|
|
@ -129,7 +124,8 @@ href="http://s3.amazonaws.com/four.livejournal/20090527/node-0.0.1.tar.gz">node- |
|
|
|
<p>Node eventually wants to support all POSIX operating systems (including |
|
|
|
Windows with mingw) but at the moment it is only being tested on Linux, |
|
|
|
Macintosh, and FreeBSD. The build system requires Python. V8, on which |
|
|
|
Node is built, supports only IA-32 and ARM processors. |
|
|
|
Node is built, supports only IA-32 and ARM processors. V8 is included in the |
|
|
|
Node distribution. There are no dependencies. |
|
|
|
|
|
|
|
<pre class="sh_none"> |
|
|
|
./configure |
|
|
|