My Fascination With Node.js and Server Side JavaScript

In my previous blog posts the state of the Windows Phone app has been the primary focus. The Windows app is very close to complete and, other than adding some features and fixing some bugs, I don’t feel like there is much to update on. Instead I thought it might be interesting to share one of my interests with you.

In my time writing code I have used many different languages. Some have been by choice and others out of necessity, and I have to say that I have had an enjoyable experience working in most of them, but there is one technology that has become more of a favorite of mine in the last couple of years. That technology is Node.js, and I want to touch on some of its history and features.

I have always felt that a good indicator of a technology’s success and future relevance has been the activity of the online community surrounding it. And Node.js has a HUGE following in the online community and will probably be a promising solution to problems for years to come. With such a large community and rapid development, there are many different blog worthy topics that I could cover, but I will focus primarily on the history of Node.js and where it excels: I/O efficiency through an asynchronous event loop.

Node.js is JavaScript. Many technology savvy people are aware of JavaScript and may have experience writing some of their own. Those who are less familiar with programming languages often confuse JavaScript for Java because the names sound similar, but they are distinctly different languages. It isn’t surprising that JavaScript (aka ECMAScrip) is so well known because it has been around since early 1995. Since its release, it has become the language for client side code in internet browsers. Today, you would have a difficult time if you were tasked with finding a web page that didn’t use JavaScript as it is used on almost every website that we visit daily.

Where Node.js comes in to the picture is that it takes JavaScript from a client’s web browser to the server or almost any other platform that you could potentially execute code on. It is interesting to note that Node.js is not the first implementation of server side JavaScript; Netscape Enterprise Server had an implementation of JavaScript when it was released in December of 1994. However, Node.js isn’t what it is simply because there was a desire to bring JavaScript to other environments. Ryan Dahl, the creator of Node.js, had a problem to solve, and that problem was that we had been using I/O inefficiently. When a connection is made to a database and we query for data, a typical program will wait for a response and then when it receives a result, do something with it. The problem is that the time in which a program is waiting for a response from the database can be at the cost of millions of clock cycles. An efficient program will be able to make a call to a database and execute other code while waiting for a response, thus utilizing resources as optimally as possible.

A programmer’s first instinct may be spooling up multiple threads, allowing the program to do other things while?waiting for a response. The problem with this is that spooling up a new thread and context switching between them is not free.?An example of this behavior can be found by examining how two web servers, Apache and NGINX specifically, handle connections. NGINX tends to handle a higher load of requests per second with less wait time than Apache. Part of this is because NGINX came onto the scene after Apache with more awareness of the concurrency problems that arise with Apache at a high scale. The difference is that Apache uses a thread for each individual connection while NGINX implements an event loop. So both servers are capable of handling multiple connections concurrently, but Apache has to context switch between threads while NGINX queues tasks for execution in an event loop. Switching context between threads adds extra overhead especially at higher loads where more threads are involved.

This is why Node.js set out to solve the I/O problem by using an event loop instead of threading. An important concept to consider is that, being human, we need to be able to write code in a way that things make sense.?Ideally we write code requesting a piece of information like we would from a database and immediately after, we do something with that data. This is where JavaScript comes in. I believe that Ryan Dahl would have chose another programming language to build Node on if it made more sense. But JavaScript being a language that was used primarily in browsers was built for event loops with its ability to pass functions around as callbacks. There are many different events happen in a browser, such as page load, button clicks, images being loaded in or many other forms of I/O. This trigger what is known as a callback function is triggered in JavaScript. This makes JavaScript very well suited for building into an event loop environment.

It is important to point out that other languages had asynchronous libraries that would handle an event loop at the time of Node.js’ conception (ex Python’s Twisted and Perl’s AnyEvent). But the problem with these libraries is that a developer would use these libraries and then want to use other libraries as well, but if the other libraries that the developer wants to use are not written with the ability to run asynchronously then they really won’t play well with the asynchronous library. Node.js had the intention of being asynchronous at its core.

Now that we have covered all of this, let’s look back at the example I have so frequently referenced where we are waiting on data from a database. We can have a function in Node.js that will handle opening a connection to the database and querying for a result. The key difference is that this function will take in a callback function. Then, Node.js will handle queueing tasks up in the event loop effectively, allowing for execution of code while we are waiting on the I/O of the database connection. When the database returns with a result, our callback function will be called with the result from the database. Thus keeping the local machines resources working as effectively as possible without any down time.

1| ? ?function getData(callback) {
2| ? ? ? ?var db = getConnection();
3| ? ? ? ?var result = db.query(?SELECT something FROM something;?);
4| ? ? ? ?process.nextTick(function () {
5| ? ? ? ? ? ?callback(result);
6| ? ? ? ?});
7| ? ?}

This example isn’t using the database connection asynchronously, but it gives you a basic idea as how this code can run. It won’t hold up any other pieces of code from running until it calls the callback function on its next tick.

Overall, I find Node.js fascinating as well as fun to work in, because you get to write asynchronous code in a completely new way. Node.js projects are quick and easy to write, and they can also run on many different platforms.?The evolution of Node.js is, and continues to be, very interesting as the large Node.js community that is constantly building new projects and libraries as well as improving Node.js as a whole.

Node.js is not without its own problems. If I were to show an example of using a database function asynchronously, we would see an example of ?Callback Hell?, a certain type of code readability issue. This is an issue in Node.js, but?has an interesting solution called ?promises? that I may discuss in a future blog post.

Leave a Reply

Your email address will not be published. Required fields are marked *