Tuesday, 27 September 2016

Events, Event Emitters and Event Loop

Now ,that you have learned about node architechture , its better time to move ahead.

First thing which we come to hear about node is ' events and event emitters'. We can say that , events are the heart of node js. So lets understand events first .

Events: 

Somthing that has happened in our app that we can respond to.

In node we actually come across two types of events.

1. System Events
2. Custom Events


|-------------------------                    |-------------------------|
|                        |                    |                         |
|                        |                    |                         |
|                        |                    |                         |
|   system events        |                    |  custom events          |
|                        |                    |                         |
|                        |                    |                         |
|                        |                    |                         |
|                        |                    |                         |
--------------------------                    --------------------------|
        c++ core                                     javascript core
         Libuv          --------------------->        Event Emitter
  

System Events:

System events come from c++ side of the nodejs core . The C++ Libuv library is responsible for Node’s asynchronous I/O operations and main event loop. It is composed of a fixed-size thread pool from which a thread is allocated for each I/O operation. By delegating these time-consuming operations to the Libuv module, the V8 engine and remainder of NodeJS is free to continue executing other requests.

Libuv deals with the events coming from the operating system like finished reading a file .  

Custom Events:

The javascript events that one creates by himself . Event emitter in node is where we have our custom events written in javascript.

now lets have look on event emitter.

Event Emitter:

All objects that emit events are instances of the EventEmitter class. These objects expose an eventEmitter.on() function that allows one or more functions to be attached to named events emitted by the object. Typically, event names are camel-cased strings but any valid JavaScript property key can be used.
When the EventEmitter object emits an event, all of the functions attached to that specific event are called synchronously. Any values returned by the called listeners are ignored and will be discarded.
The following example shows a simple EventEmitter instance with a single listener. The eventEmitter.on() method is used to register listeners, while the eventEmitter.emit() method is used to trigger the event.
const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}

const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
  console.log('an event occurred!');
});
myEmitter.emit('event');

now lets see that event occourred is true or not . Here is what i got when run this piece of code to my node console.



and yes , it returned true saying 'an event occurred !' .


for more eager ones here is the whole meat of events at https://nodejs.org/api/events.html .

Lets understand the Level of abstraction in nodejs as how an event travels at each level.


Level of abstraction:

Here is description of how events travel .

                    |          javascript  (event emitter)
                    |            
                    |          c/c++   (libuv)
                    |
                    |          Assembly Language
                    |        
                    |          Machine Language
                    v


Node is written in c++ ,not javascript

Node is written in c++. though it seems surprising that we write all the codes in javascript . Yes alright , we write all the codes in javascript say functions , methods and all , and when we require any node library , even then we use javascript . but let me tell you , Node is itself written in c++.  And the main reason why node is written in c++ is because v8 , the engine is written in c++. v8 converts javascript to machine code .So node , which is onto it ,is written in c++. 


for v8 details , here are the good contents https://developers.google.com/v8/intro and also visit this v8 blog http://v8project.blogspot.in/ . Download the source code and look into it. It is c++.



Lets go deep into event loops now .

Event driven programming

This style of programming — whereby instead of using a return value you define functions that are called by the system when interesting events occur — is called event-driven or asynchronous programming. This is one of the defining features of Node. This style of programming means the current process will not block when it is doing I/O. Therefore, several I/O operations can occur in parallel, and each respective callback function will be invoked when the operation finishes.

Event Loops


The event-driven programming style is accompanied by an event loop. An event loop is a construct that mainly performs two functions in a continuous loop — 

1.event detection and 

2.event handler triggering. 

In any run of the loop, it has to detect which events just happened. Then, when an event happens, the event loop must determine the event callback and invoke it.

This event loop is just one thread running inside one process, which means that, when an event happens,the event handler can run without interruption. This means the following:
➤ There is at most one event handler running at any given time.
➤ Any event handler will run to completion without being interrupted.
This allows the programmer to relax the synchronization requirements and not have to worry about concurrent threads of execution changing the shared memory state.

The event loop gives Node the capability to handle highly concurrent requests while still running “single-threaded”. In any event-driven application, there is generally a main loop that listens for events, and then triggers a callback function when one of those events is detected. Similarly, the event loop delegates I/O operations via POSIX interface while it still handles new requests and callbacks. Here is my take on how things work inside the node.js server:




The event loop simply iterate over the event queue which is basically a list of events and callbacks of completed operations. All I/O is performed asynchronously by the threads in the thread pool. Libuv component of Node.js plays a vital part in this. If an item requires an I/O the event loop simple delegates the operation to the thread pool. Event loop continues execution of items in the event queue. Once the I/O operation is complete, the callback is queued for processing.. Event loop executes the callback and provide appropriate results. Since, it’s in a loop.. The process simply keeps going.






Understanding Architecture of NodeJS

Technology

V8 Runtime Environment
Google’s V8 engine is an open-source Just In Time, or JIT, compiler written in C++.
 In recent benchmarks, V8’s performance has surpassed other JavaScript interpreters including SpiderMonkey and Nitro. It has additionally surpassed PHP, Ruby and Python performance. Due to Google’s approach, it is predicted that in fact it could become as fast as C. The engine compiles JavaScript directly into assembly code ready for execution by avoiding any intermediary representations like tokens and opcodes which are further interpreted. The runtime environment is itself divided into three majors components: a compiler, an optimizer and a garbage collector.


Libuv

The C++ Libuv library is responsible for Node’s asynchronous I/O operations and main event loop. It is composed of a fixed-size thread pool from which a thread is allocated for each I/O operation. By delegating these time-consuming operations to the Libuv module, the V8 engine and remainder of NodeJS is free to continue executing other requests

Design Patterns

Node relies heavily on
1. Object Pool
2. Facade
3. Factory Design Patterns

NPM

The Node package manager, denoted npm, is the official package manager for NodeJS, written entirely in JavaScript. It comes bundled and installed automatically with the Node environment. It is responsible for managing dependencies for the Node application and allows users to install applications already available on the npm registry. Npm was initially developed in 2010 with the immediate goal for quick integration into the NodeJS platform.

Official site : https://www.npmjs.com/

Internal Structure of Nodejs.


The internal structure of NodeJS. The main, single thread handles all incoming requests concurrently. All components are single-threaded, promote asynchronous behavior, and are able to interface with one-another. All connections are highspeed and enabled through streams of data.


Architectural Style of  Nodejs.


The various interactions between NodeJS platform components during a single Node instance. This demonstrates where how the event loop delegates tasks to a thread allocated by the Libuv library and allows for an asynchronous solution. below is the reference diagram.



This example depicts a simple example of a Node JS request to access data from a database. Here, the platform acknowledges the request immediately before writing or reading any data.



Above data provided are written in reference to An Inside Look at the Architecture of NodeJS  by Benjamin San Souci McGill University .

Nodejs Environment Setup in Windows

Getting Nodejs:

We will focus on following :

  • Install and setup node.js on windows.
  • Run a “Hello world!”-program.
  • Create a webserver program.

Installation:

Nodejs can be downloaded from https://nodejs.org/en/download/ . Here choose for windows installer for 32 and 64 bit OS. Choose the Current version or most recommended version. When download finishes , go to .msi installer and install it . Now you are done with the installation.
Go and open windows search menu and type nodejs to open nodejs console and type the first command 

> node
and you will be prompted to node console and can access all its functionalities.

Runnig A 'Hello World' program:

After opening console , now lets create a js file . Lets say it index.js and enter the following into this js file.


console.log("Hello World");
    and save it .
Now lets open the Nodejs console and browse to index.js file .
and simply type 

> node index.js


and it will output 

Hello World

in the console.


Create a webserver program:

Now we can use the program we encountered in the Introduction .

Copy this code Snippet into your index.js 
const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

and run again the command
> node index.js

you will see a message in the console as 


> Server running at http://127.0.0.1:3000


now open your browser and go to url mentioned in the above program.
i.e.  http://127.0.0.1:3000 .
and you wil see 'Hello World'.



Congreates !! you have successfully made an http connection .

In the next  section we will understand nodejs architecture.

Introduction to Nodejs

Definition: 
Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js uses an event-drivennon-blocking I/O model that makes it lightweight and efficient.

Nodejs is developed by Ryan DahlYou can see detailed description of Nodejs video on YouTube , Introduction to Node.js by RyanDahl where he exactly shows how node can be a lot faster than previous synchronous events.



As an asynchronous event driven JavaScript runtime, Node is designed to build scalable network applications. In the following "hello world" example, many connections can be handled concurrently. Upon each connection the callback is fired, but if there is no work to be done Node is sleeping.



const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World\n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

This is in contrast to today's more common concurrency model where OS threads are employed. Thread-based networking is relatively inefficient and very difficult to use. Furthermore, users of Node are free from worries of dead-locking the process, since there are no locks. Almost no function in Node directly performs I/O, so the process never blocks. Because nothing blocks, scalable systems are very reasonable to develop in Node.


now open your browser and go to url mentioned in the above program.
i.e. http://127.0.0.1:300
and you wil see 'Hello World'.

Congreates !! you have successfully made an http connection .
Now Lets move on with node setup , in case you are perfect beginner .