node.js


Nodejs Microsservices



To run nodejs scalably (link)
Multiple cores: norejs clusters
Multiple machines: nginx link1, link2  Have multiple machines each running the same replica of server, run nginx reverse proxy to load balance between them





gulp.js is workflow management for node.js like azkaban for hadoop

$ node
>1 + 2 
3
>function add(a,b){return a+b}
undefined
> add(1,2)
3


html boilerplate
app.param
$ npm install -g nodemon   //automatically restart. make sure you call the start script section of package.json   like   node-dev   module
$ npm search   # list all available packages
$ npm search markdown  # will list all markdown packages
$ npm init   # to initialize package.json
$ npm update # to update modules for this project
$ sudo npm update -g  # update all global modules
$ npm prune   # remove any packages you've removed from your dependency list





//print attributes and functions of an object
function getMethods(obj) {
  var result = [];
  for (var id in obj) {
    try {
   //   if (typeof(obj[id]) == "function") {
        result.push(id + ": " + obj[id].toString());
    //  }
    } catch (err) {
      result.push(id + ": inaccessible");
    }
  }
  return result;
}





Non-blocking I/O

Whenever we want to do a blocking I/O we register a call-back function - hence make it non-blocking! So we don't actually wait for bit.ly to return with a response.      Reactor is what handles the non-blocking
  • Eventually non of these requests are running side by side, but they are running one at the time -
  • The main benefit is that during red segments we can handle new requests.
  • So in Node each process can handle multiple requests unlike rails e.g. that each process does only one.
  • So, we don't have to start as many node processes as we would with ruby for the same amount of load
  • Response latency is first. if you only have one user these don't differ from ruby to node
  • node is hard to read, leads to spaghetti of nested callbacks
  • Rails has event manager for evented programming and callbacks.
    • We are scheduling the I/O by ourselves. in Ruby programming we are unaware of IO
 
 
 
 



Standard Python is actually slower in 46 of the 50 problems. In 28 of the 46 node is faster by a factor of 10 or greater, in 9 of those 28 by a factor of 50 or greater and in 2 of the 9 by a factor of 100 or greater! The only 4 in which Python was faster were from the n = 10000 sample.

$ vim hello-world.js
  setTimeout(function(){
      console.log("world");
   }, 2000)
   
   console.log("Hello ");

In node.js you never sleep, no mutex, lock, etc
PHP:
  echo("Hello");
  sleep(2) //sleep!!!
  echo("World")

returns when there is nthing left to do
$ vim hello-world-interval.js
setInterval(function(){
      console.log("world");
   }, 2000)
   
   console.log("Hello ");

hello
world
world
world
...



In java script you have document which is dom but in node.j you have process.


server

$ vim web-server.js
var http = require("http")

var s = http.createServer(function(req, res){ //has a call back funciton which is called whenever a request is received at teh server.
    res.writeHead(200, {"content-type" : "text/plain"})
    res.end("hello world.\n")
}) 

s.listen(8000)

$ node web-server.js
$ curl http://localhost:8000/
hello world.
$ curl -i http://localhost:8000/
HTTP/1.1 200 OK
content-type: text/plain
Date: Wed, 18 Sep 2013 17:51:27 GMT
Connection: keep-alive                                    there is persistent connection to the webserver
Transfer-Encoding: chunked

hello world.

Transfer-Encoding: chunked
$ vim web-server-chunked.js
var http = require("http")

var s = http.createServer(function(req, res){
    res.writeHead(200, {"content-type" : "text/plain"})
    res.write("hello\n")           //writes and doesn't wait for all to be ready
    setTimeout(function(){
         res.end("wold.\n")
    }, 2000)
}) 

           s.listen(8000)
if we set content-length=12 it didn't work. we don't want to buffer it. but proxy it to client. send directly back to client.
if we make two curls at the same time both of them work simulaneously. otherwise if we were sleeping one would have to wait for hte other to finish.

TCP sevrer

net = require('net')

var sockets = []

var s = net.Server(function(socket){
    sockets.push(socket)
    socket.on('data', function(d){
        for(var i = 0; i < sockets.length; i++){
            if(sockets[i] == socket) continue
            socket[i].write(d)
        }
    })

    socket.on('end', function(){
        var i = sockets.indexOf(socket)
        sockets.splice(i, 1)
    })
})    //createServer/
 
$ nc localhost 8000

================

npm (node package manager) is equivalent t gem for ruby

express.js is web framework.

array.join(" ") //concat array element


 Node v8 Engine
 Google chrome
 global window
require
 location
 module document
 process 
 consoleconsole

Module

module.exports
a javascript file.
module.exports = function(){} ...........  //created exported fcn
Then when we say
var my_fcn = require('./myfilename')       //require: if there is a file with that name or a folder with that name and an index.js file in it
we can do
my_fcn()
exports.mypropertyname
exports.myfcn1 = function(){}
exports.myfcn2 = function(){}
then:
var a  = require('./myfilename')
a.myfcn1()
a.myfcn2()
Any variable defined in js fiels will be global and when you require a module you can reset those variables. to make it local define it using var

you can also pass a parameter to module: like 


// lib.js
module.exports = function(options) {
var app = options.app;
var param2 = options.param2;
};

// somefile

require("lib.js")(params);


OR
// lib.js
module.exports = function(app, param2) { }
// somefile
require("lib.js")(app, param2)
Create a module to get and set flight data


Create a module to get and set flight data
var number, origin, destination;

exports.setNumber = function (num) {
    number = num;
};

exports.setOrigin = function (o) {
    origin = o;
};

exports.setDestination = function (d) {
    destination = d;
};

exports.getInfo = function() {
    return {        //in line literal object
        number: number,
        origin: origin,
        destination: destination
    };
};


later we can do var a = require('./myfile'); a.setDestination('temp')

var os = require('os');
console.log('This code is running on: ' + os.type());

$ npm install --save express   # to install and save it in package.json


Node Packaged Modules (NPM)
$ mkdir myproject
$ cd myproject
$ npm init                                             # Morteza Shahriari Nia <m.shahriarinia@gmail.com>
$  npm install --save express               # download dependency and add its version details to package.json      
$ vim index.js
var http = require('http'),
      express = require('express');

var app = express();

app.get('/', function(req, res) {
    res.end('Airline');
});

http.createServer(app).listen(3000);
$ node index.js


Global modules
$ sudo npm install -g express-generator       # creates express as a global module and as a commandline command for generating express modules    

$ express mynewproject
$ cd mynewproject
$ npm install
$ npm start    # runs the node index.js of the project as declared in the package .json

you can remove a dependency from package.json then call
$ npm prune  # to remove its directory

you can manually add a dependency to package.json. * declares use the latest version
    "jade": "*"
$ npm update   # will update the modules


Cool Modules

readline
jquery
use jquery without web browser
var argv = require('optimist').argv,
    $ = require('jquery'),    
    fs = require('fs');

var file = argv._[0];

var html = fs.readFileSync(file, 'UTF-8');

$(html).find('p').each(function(index) {
    var content = $(this).html();

    console.log('Paragraph ' + (index + 1) + ': ' + content);
});
jshint     # detect potential problems with your code before you actually run it. Use its sublime package. command shift j
connect  # for static content ; Connect makes it possible for you to handle multiple kinds of requests by chaining calls to connect to use.
var connect = require('connect');

var app = connect()
    .use(connect.static('public'))
    .use(function (req, res) {  //error handling
        res.end("Couldn't find it.");
    })
    .listen(3000);

=========================

var connect = require('connect');

var app = connect()
    .use(connect.bodyParser())
    .use(connect.static('public'))  //serve anything that is static in public directory e.g. if you put the index.html there
    .use(function (req, res) {   //the rest
        if (req.url === '/process') {
            res.end(req.body.name + ' would repeat ' + req.body.repeat + ' times.');
        } else {
            res.end("Invalid Request");
        }
    })
    .listen(3000);

=========== modify http parameters
        res.setHeader('Content-Type', 'application/json');
        res.end(JSON.stringify(my_data));





for static variables of an object define object in a file and use vars in the file which are local to the file (module) for handling static stuff

Stream file system

var fs = require('fs');

var stream = fs.createReadStream('data.json');  //create a stream out of data.json instead of reading all at once and storing it in memory

stream.on('data', function (chunk) {
    console.log('----------------begin chunk----------------');
    console.log(chunk.toString());
    console.log('----------------end chunk----------------');
});


stream.on('data', function (chunk) {
    console.log('CHUNK LENGTH WAS: ' + chunk.length);
});

stream.on('end', function  () {
    console.log('----------------reached file end----------------');
});


Pause a stream
stream.pause()

setTimeout(function() {
    console.log('resuming...');
    stream.resume();
}, 1000);

Piping readable data into writable streams create a copy of the data
var fs = require('fs');

var stream = fs.createReadStream('data.json'),
      writable = fs.createWriteStream('copy.json');

stream.pipe(process.stdout);

stream.pipe(writable);

Duplex (both read and writable streams)
var net = require('net'),
  fs = require('fs');

var server = net.createServer(function  (connect) {

  var log = fs.createWriteStream('eli.log');

  console.log('Connection established');

  connect.on('end', function() {
    console.log('Connection ended');
  });

  connect.write("Welcome to our airline customer hotline.\r\n");
  connect.write("We call it ELI: the Electronic Listening Interface.\r\n");
  connect.write("We'll repeat back your message and log it for further review.\r\n");

  connect.pipe(connect).pipe(log);

});

server.listen(7777, function() {
  console.log('Server ready on port 7777');
});

 $  telnet localhost 7777     # will let you write stuff for it












Subpages (2): express SQL ORM
ċ
myproject-after-adding-data-as-param.zip
(35k)
Morteza Shahriari Nia,
Dec 2, 2014, 9:00 PM
ċ
myproject-before-unit-test.zip
(31k)
Morteza Shahriari Nia,
Dec 2, 2014, 6:09 PM
ċ
myproject-final.zip
(40k)
Morteza Shahriari Nia,
Dec 4, 2014, 1:08 PM
ċ
myproject-mongo-session.zip
(37k)
Morteza Shahriari Nia,
Dec 3, 2014, 3:34 PM
ċ
myproject-tests-done.zip
(35k)
Morteza Shahriari Nia,
Dec 2, 2014, 9:45 PM
Comments