Thursday, May 30, 2013

Node.JS behind the scenes. What's the difference between Node.JS and IIS ?

The first thing you think about when you hear the word 'JavaScript' - is about developing client-side web-pages. It's perfect to interact with the DOM of the page, and handling DHTML.
Well, JavaScript is more than that. It's a prototype-base programming language in the full sense of the word.
Node.JS is a server written in JavaScript, based on Google's new V8 JavaScript engine, and it's an event-driven, non-blocking I/O model.
Node.JS is a single-process, unlike other servers like Apache (that runs PHP) which starts its own process for every HTTP Request.

When writing Node.JS code, there will always be a use of one of the most powerful and important JavaScript features: Callback functions. That is the whole idea of asynchronous programming, and that would keep your single Node.JS process running fast. 
With callback functions, you can avoid blocking code.

Here is an example of how NOT doing it. 

Synchronous code:
var result = database.query("SELECT * FROM hugetable");
console.log("Hello World");

Suppose getting the results from the database takes several seconds. The single Node.JS process will be halt, and other requests would not be handled until receiving a response. Same same as for the "console.log("Hello World")" line. If this synchronous code was written in PHP, other requests 
won't get affected by that blocking code (each process for every request).

Here is an example of how doing it, using the concept of event-driven.

Asynchronous code:
function dbRows(rows)
{
  var result = rows;
}

var result = database.query("SELECT * FROM hugetable", dbRows);
console.log("Hello World");


By giving the second argument, which is the callback function, the single Node.JS process won't be halt, and "Hello World" would be printed. If you are writing your code in ASP.NET, then your web-application is served on w3wp.exe process, which is a single-process just like Node.JS. On MVC 2.0, you can implement "AsyncController" for asynchronous methods, or you can do it without MVC with "IHTTPAsyncHandler" interface.


So what is the difference between Node.JS and ASP.NET Async ?


First of all, the whole concept of Node.JS is "event-driven". That means it's very easy to write Asynchronous application. So an average Node.JS programmer will think Async, and an ASP.NET one - it wouldn't really matter. That because synchronous code in .NET would be much more readable than async one. Furthermore, writing a complete ASP.NET Async application is simply harder.

In addition, if a Node.JS developer is using external libraries (=modules), probably those would be Async, but with .NET you cannot be sure about it.

In order to implement Async, .NET uses I/O completion ports. Many .NET libraries don't use them. For example: ADO.NET supports Async (Engine is using completion ports) while Entity Framework doesn't (engine is NOT using completion ports).
ASP.NET dedicates a thread per request from its thread pool and it has a maxmium number of working threads. In case of a blocking code (Synchronous code), new threads would be created and other threads would be stuck doing nothing (using CPU resources), and if that doesn't enough - the application can run out of threads as you define it on the web.config:











Request Flow


Although people tend to think Node.JS is single-threaded - it's not. It uses the event-loop as a manager to transfer work from the clients to the C++ thread pool (= Gets requests from the clients and send them to thread workers). 
When the work gets done, it transfer the response back to the client.
Back to the threads thing. The event-loop (which is a permanant thread) runs on the same - single I/O thread, BUT the work it delivers is done multi-threaded behind the scenes.
In Windows and Linux, each user mode thread has a kernel mode thread (one-to-one threading model). If the user mode thread needs to use the kernel thread (in order to perform privileged instructions, such as process creation or I/O operations) it does it by system calls.
Node.JS threads (Event loop thread and C++ ThreadPool workers) are working on user mode only.

So "everything runs in parrallel except your code". Your Node.JS code doesn't contain any threads.
Node.JS built upon LibUv library, which provides the event loop mechanism. That mechanism allows a task to be registered on the ThreadPool and get a response once the task completed (uses
the callback function in order to send the response).


IIS 6.0 request flow is more efficient than IIS 5.0 (or less version): 


1. The kernel receives a request and delivers it to HTTP.SYS
2. HTTP.SYS delivers the request to the target worker process (the one that belongs to the requested application pool)
3. Worker process uses a thread pool to process the request
4. Worker process sends the response back to HTTP.SYS which delivers it to the client



A short explanation about Thread Context Switches


Context switches (CPU switch between threads) occur in one of those situations:
1. A running thread voluntarily releases the processor
2. Kicked out by a higher priority ready thread
3. Might happen when switches between user-mode and privileged (kernel) mode to use an Executive or subsystem service (that switch is a mode switch, not context switch. Context switch has heavy performance penalty. Sometimes mode switch causes context switch).


Performance Differences


- When a request is being made : The kernel thread delivers it to the IIS I/O thread gets, which post it to the   CLR ThreadPool and gets a "pending" status from it.

On step 1 - there is a mode switch between kernel and user-mode, so there might be a context switch.
The IIS/IO thread waits for the "pending" status from CLR ThreadPool in order to continue. So there is a context switch, and the IIS/IO gets blocked.
On step 4 - there is a mode switch, so there might be a context switch as well.

On Node.JS, the request is passed from event-loop thread to C++ ThreadPool (both running on user-mode). BUT, if there are many requests there queued on the event-loop and the ThreadPool thread can pick up a bunch of requests and not just one like the IIS does.

- In case of a small number of requests - IIS should perform better.
In IIS, each request gets only one thread from the ThreadPool. In Node.JS, a request can be transferred between threads from the ThreadPool (And  that means more context switching). 

- In case of a large and concurrent number of requests - Node.Js should perform faster because it has fewer threads and includes the event-loop architecture (non-blocking I/O), so there will be less context switches and heavy load performs well on event-loop architecture.
IIS has larger ThreadPool, so the requests will use them all - and there will be more context switches. 

- In case of serving static HTML pages - IIS has a real significant advantage on Node.JS, because it has kernel mode caching, so the request won't arrive to user mode.


For conclusion

There isn't a straight answer which server is faster. It depends on your application needs. Basically, you should use Node.JS when receiving a lot of concurrent requests and heavy load.
One thing is for sure: Async code is more efficient than Sync code.


Ok, enough with performance. Besides that, why should I use Node.JS ?

1. It's open source. The community is growing, and you can find a variety of libraries for your server application. There are many implementations for every task, and no need to pay for license.
2. It's a low-level, lightweight and standalone framework.
If you want to install IIS, you need to install the whole .NET framework. That's heavy.
3. It's cross-platform. For example: you can write Node.JS code in Windows environment, and move it to Linux with ease.
4. No multithreading / locking bugs. As mentioned, your code doesn't include threads.
5. It's very easy to write Asynchronous code (which is efficient than synchronous code) and thus create non-blocking I/O.
6. You can use the same javascript code in the client and the server. For example: form validation.
7. JavaScript is becoming more and more popular. Now, a company can hire a developer for both client and server programming (Unlike C#, PHP and so on).
8. You can also check out this cool article: http://www.toptal.com/nodejs/why-the-hell-would-i-use-node-js  which explains the benefits of node.js.

And why not ?

1. There isn't a remarkable IDE for developing Node.JS server application. 
I'm working currently with "Notepad++" text editor, and "node-inspector" for debugging.
2. Async code is not readable as Sync code.
3. Node.JS is a young and immature framework. You should closely check the libraries you choose to add to your server application. Some of them can have insufficient documentation and support on the web. Some of the APIs change across versions, and some will die.
4. No convenient local server hosting manager (like IIS). You can deploy your server applications to cloud solutions (nodejitsu, nodester and so on..), but I couldn't find a server local manager tool for all the apps.

What about use-cases ?

I think that post: http://nodeguide.com/convincing_the_boss.html explains it well.

Finally, which web-sites already uses Node.JS ?

https://github.com/joyent/node/wiki/Projects,-Applications,-and-Companies-Using-Node

Thank you Blogger, hello Medium

Hey guys, I've been writing in Blogger for almost 10 years this is a time to move on. I'm happy to announce my new blog at Med...