Sunday 3 July 2016

Node.js Event Model: A Paradigm Shift

When I first started working with node.js few years back I found it little difficult to understand some of the basic concept of the event model of it initially. Especially the way we call functions from another functions in node.js is totally different as opposed to the traditional approach. In general all the function call comes with a callback function in node.js. Why is that? What was wrong in the traditional way (synchronous) of calling a method.

A Quick Look at the Threaded Model

Let's get a step back and see how the conventional way of function calls work. We call it a threaded model as each request comes to server initiates a new thread and all the subsequent work happens in the same thread until the request is complete and response is sent to the client (caller). The figure below tries to illustrate the same. 

Fig 1: Request in a threaded model

There are two requests to get a file (downloadFile) and to get some user data (getUserDetails). The downloadFile request opens the file, reads the contents, and then sends the data back in a response. All this occurs in order (sequence) on the same thread. The getUserDetails request connects to the database, queries the necessary data, and then sends the data in the response. 


The problem arises when any of the threads is working on some I/O operation and waiting for some response. For example when Thread 2 tries to connect to the DB, the thread will become idle until the response comes from the DB. If the network latency is little high it will take a while and during that time the CPU cycles are not utilized. Likewise if there are lot of concurrent requests and threads are busy in blocking I/O, after some point of time there may be a crunch situation if the existing thread pool. Hence the subsequent request won't be served. This also leads to high memory usage as the threads pool is exhausted.

How Node.js Approaches the Same Problem

Node.js provides scalability and performance through its powerful event-driven model. Node.js applications run in a single-threaded event-driven model. Although Node.js implements a thread pool in the background to do work, the application itself doesn’t have any concept of multiple threads. “Wait, what about performance and scale?” you might ask. At first a single-threaded server might seem counterintuitive, but once you understand the logic behind the Node.js event model, it all makes perfect sense.

Instead of executing all the work for each request on individual threads, Node.js adds work to an event queue and then has a single thread running an event loop pick it up. The event loop grabs the top item in the event queue, executes it, and then grabs the next item. When executing code that is longer lived or has blocking I/O, instead of calling the function directly, it adds the function to the event queue along with a callback that will be executed after the function completes. When all events on the Node.js event queue have been executed, the Node.js application terminates.

The below figure illustrates how Node.js handles the downloadFile and getUserDetails requests. It adds he downloadFile and getUserDetails requests to the event queue. It first picks up the downloadFile request, executes it, and completes by adding the Open() callback function to the event queue. Then it picks up the getUserDetails request, executes it, and completes by adding the Connect() callback function to the event queue. This continues until there are no callback functions to be executed. Notice that the events for each thread don’t necessarily follow a direct interleaved order. For example, the Connect request takes longer to complete than does the Read request, so Send(file) is called before Query(db).

Fig2: Node.js Event-driven Model


Blocking I/O in Node.js

Some examples of blocking I/O are:


  • Image Reading a file
  • Image Querying a database
  • Image Requesting a socket
  • Image Accessing a remote service

Node.js uses event callbacks to avoid having to wait for blocking I/O. Therefore, any requests that perform blocking I/O are performed on a different thread in the background. Node.js implements a thread pool in the background. When an event that blocks I/O is retrieved from the event queue, Node.js retrieves a thread from the thread pool and executes the function there instead of on the main event loop thread. This prevents the blocking I/O from holding up the rest of the events in the event queue.After the execution gets completed the thread will go back to the thread pool.

The function that is executed on the blocking thread can still add events back to the event queue to be processed. For example, a database query call is typically passed a callback function that parses the results and may schedule additional work on the event queue before sending a response.

The figure below illustrates the full Node.js event model, including the event queue, event loop, and thread pool. Notice that the event loop either executes the function on the event loop thread itself or, for blocking I/O, executes the function on a separate thread.

Fig 3: Node.js Event-driven model with thread pool


Conclusion

The advantage of this approach is the main thread is never become idle and no CPU cycles are wasted. At the same time memory foot print of the server is also pretty less. The event-driven model is doing the trick for node.js.

Reference:
Link: https://nodejs.org/en/docs/

Book: Node.js, MongoDB, and AngularJS Web Development by Brad Dayley


Friday 1 July 2016

OpenLayer: Quick Start to Your Mapping App

Recently I have started exploring how to develop a web map application with interactive facility. Since last few years the popularity of interactive web maps has exploded. There are many free services which provides map data these days including Google, Bing Maps, OpenStreetMap etc. My intention is to create a simple app using one of these open API.

The interactive map app can be useful in many places, e.g. digitization of land, roads, railways etc. and to give users search feature hence better maintainability. It can be helpful in digitizing the real estate industry as well in terms of maintaining land records for a specific owner, agricultural lands.

In this post we will build a simple app using OpenStreetMap and OpenLayer 3.0. OpenStreetMap (http://www.openstreetmap.org/) is one of the popular open source Geo Map services which helps us working with map. This will work as a Web Map Server (WMS) in the server side. 

OpenLayers is an open source, client-side JavaScript library for making interactive web maps, viewable in nearly any web browser. Since it is a client-side library, it requires no special server-side software or settings—you can use it without even downloading anything! 

To keep it simple OpenLayer provides layer approach where we can request and map data from any map server and add it. For instance, if you wanted to have a Bing Maps and an OpenStreetMap service displayed on your map, you would use OpenLayers to create a layer referencing Bing Maps and another one for OpenStreetMap, and then add them to your OpenLayers map.

The latest version of OpenLayer 3 can be downloaded from here.
Go to the site and download the zip file (e.g. v3.16.0.zip). Extract the zip and you will find build and css folder inside it.

Create the following folder structure:



Copy the files from the previous build folder into the ol3/js folder and also copy the files from the above css folder into the same ol3/css folder (see image above).After the copy your folder structure should look like as below:




Let's dive into OpenLayers and make a map! After you finish this section, you should have a working map, which uses a publicly available OSM server backend from the OpenStreetMap.org project. Execute the following steps:

Navigate to the assets directory, create a folder css, and create a new file called samples.css. Add the following code:

map {
height: 500px;
width: 100%;
background-color: #b5d0d0;
}

Add the following code to a new file called helloWorld.html and save the file in the sandbox directory. If you are using Windows, we suggest using Notepad++ in particular because you need to be sure you're editing UTF-8 encoded files. On Linux, you can use Gedit or Geany and for Mac OSX, you can use Text Wrangler (free but not open source). Do not try to edit the file in a program such as Microsoft Word, as it will not save properly. The following code will also be used as the base template code for many future examples in this book, so we'll be using it often and coming back to it a lot:

<!doctype html>
<head>
<title> Hello OpenStreetMap </title>
<link rel="stylesheet" href="../assets/ol3/css/ol.css" type="text/css" />
<link rel="stylesheet" href="../assets/css/samples.css" type="text/css" />
</head>
<body>
<div id="map" class="map"></div>
<script src="../assets/ol3/js/ol.js">
</script>
<script>
var osmLayer = new ol.layer.Tile({
source: new ol.source.OSM()
});
var birmingham = ol.proj.transform([-1.81185, 52.44314], 'EPSG:4326', 'EPSG:3857');
var kolkata = ol.proj.transform([88.36, 22.57], 'EPSG:4326', 'EPSG:3857');
var monterey = ol.proj.transform([-121.8947, 36.6002], 'EPSG:4326', 'EPSG:3857');
var view = new ol.View({
center: monterey,
zoom: 10
});
var map = new ol.Map({
target: 'map'
});
map.addLayer(osmLayer);
map.setView(view);
</script>
</body>
</html>




Open helloWorld.html in your web browser, you will see your first map created with zoom in and zoom out feature.

Find the code in github.