verona21/05/2011
gabriele lanagabriele.lana@cleancode.it  twitter: @gabrielelana
why         node.js?“Nodes goal is to  provide an easy   way to buildscalable network    programs”              http://nod...
what is                  node.js?•   asynchronous i/o framework•   core in c++ on top of v8•   rest of it in javascript•  ...
Single threadsynchronous I/0
Single threadsynchronous I/0
multiple threadsynchronous I/0
multiple threadsynchronous I/0
you can  “always” scale with  multiplemachines but  it costs  you $$$
but...what is HE doing?
CPU BOUND          TASKS?  but...what is HE doing?
CPU BOUND          TASKS?             ...OR I/o  but...       BOUNDwhat is HE    TASKS? doing?
synchronous I/0function productsInCart(request, response) {    var db = new Db()    var user = new User(request)    if (us...
synchronous I/0function productsInCart(request, response) {    var db = new Db()    var user = new User(request)    if (us...
synchronous I/0function productsInCart(request, response) {    var db = new Db()    var user = new User(request)    if (us...
synchronous I/0function productsInCart(request, response) {    var db = new Db()    var user = new User(request)    if (us...
single threadasynchronous I/0
single threadasynchronous I/0           I am       “callback”         call me         if you        need me...
hello_world_server.js                                          Event Emitter                        var http = require("ht...
hello_world_server.js                                          Event Emitter                        var http = require("ht...
hello_world_server.js                                          Event Emitter                        var http = require("ht...
hello_world_server.js                                          Event Emitter                        var http = require("ht...
Event Emittercoder@apollo:~/Work/src/node/examples$ node hello_world_server.js> SERVER STARTED                            ...
Event Emitter                        var server = require("http").createServer()hello_world_server.js                     ...
hello_world_server.js                                          Event Emitter                        ...                   ...
Event Emittercoder@apollo:~/Work/src/node/examples$ node hello_world_server.js> SERVER STARTED                            ...
why socomplicated?
data streamS                  server.on("request", function(request, response) {                    var chunks = [],      ...
data streamScoder@apollo:~/Work/src/node/examples$ node stream_doubler.js                                                 ...
why                 javascript?•   Friendly callbacks•   ubiquitous (well known)•   no I/o primitives•   one language to r...
web applications                             before: a webmind shift #1               server with some                    ...
web applications                        after: an applicationmind shift #1             accessible over                    ...
web applications                        after: an applicationmind shift #1                 that can                       ...
web applications                    before: statefulmind shift #2   • no easy to scale                • no easy to reuse  ...
web applications                    before: statefulmind shift #2   • no easy to scale                • no easy to reuse  ...
web applications                    before: statefulmind shift #2   • no easy to scale                • no easy to reuse  ...
web applications                    after: statelessmind shift #2      • easy to scale                   • easy to reuse  ...
web applications                    after: statelessmind shift #2      • easy to scale                   • easy to reuse  ...
web applications                       after: statelessmind shift #2                http                       web server ...
no fluffjust stuff
What aboutcpu bound  tasks?
the forklong_running_job.sh                          be with you                      #!/bin/bash                      for...
the forklong_running_server.js                              be with you                         var spawn = require("child...
the fork                                     be with youcoder@apollo:~$ ab -c 1 -n 1 "http://localhost:8080/"...Concurrenc...
the fork                                     be with youcoder@apollo:~$ ab -c 2 -n 1 "http://localhost:8080/"...Concurrenc...
enter cometw at   chwatch          M                spawn   ch atw               watch           w                       w...
enter cometdemo
INSTALL NPM                                     (node packet manager)coder@apollo:~/Work/src/node/examples$ curl http://np...
server/                                                      routingprogress_server.js                     var server = co...
server/                                                       routingprogress_server.js                     resource.post(...
server/                                                   socket.ioprogress_server.js                     io.listen(server...
server/                                                       simulationprogress_server.js                     server.list...
interface/html             <html>               <head>                 <title>Node.js - Long Running Jobs</title>         ...
interface/                                            socket.io             <html>               ...               <script...
interface/                                          progress bar              $.fn.progressBar = function(id, progress) { ...
interface/                                       progress bar              $.fn.otherwise = function(ifNotFound) {        ...
we can do itwith a littlemore “style”
server/                                                   event emitter                     var Job = (function() {       ...
server/                                               event emitterprogress_server.js                     resource.post("/...
node.js is awesome but when should i  use it?
when to use it?•   chat/messaging•   real-time applications•   intelligent proxies•   high concurrency applications•   com...
please tellme something bad about  node.js
some warnings•   release stable 0.4.7 (young)•   lots of stuffs to look at•   lots of half backed stuffs•   retro compatib...
vs
Questions?
gabriele lana   gabriele.lana@cleancode.it     twitter: @gabrielelanahttp://joind.in/3359
Introduction to Nodejs
Introduction to Nodejs
Introduction to Nodejs
Upcoming SlideShare
Loading in...5
×

Introduction to Nodejs

16,664

Published on

Introduction to Nodejs with examples

Published in: Technology
0 Comments
26 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
16,664
On Slideshare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
585
Comments
0
Likes
26
Embeds 0
No embeds

No notes for slide

Introduction to Nodejs

  1. 1. verona21/05/2011
  2. 2. gabriele lanagabriele.lana@cleancode.it twitter: @gabrielelana
  3. 3. why node.js?“Nodes goal is to provide an easy way to buildscalable network programs” http://nodejs.org/#about
  4. 4. what is node.js?• asynchronous i/o framework• core in c++ on top of v8• rest of it in javascript• swiss army knife for network related stuffs• can handle thousands of concurrent connections with minimal overhead (cpu/memory) on a single process
  5. 5. Single threadsynchronous I/0
  6. 6. Single threadsynchronous I/0
  7. 7. multiple threadsynchronous I/0
  8. 8. multiple threadsynchronous I/0
  9. 9. you can “always” scale with multiplemachines but it costs you $$$
  10. 10. but...what is HE doing?
  11. 11. CPU BOUND TASKS? but...what is HE doing?
  12. 12. CPU BOUND TASKS? ...OR I/o but... BOUNDwhat is HE TASKS? doing?
  13. 13. synchronous I/0function productsInCart(request, response) { var db = new Db() var user = new User(request) if (user.isAuthorized("cart/products")) { response.write( JSON.stringify( db.productsInCart(user.cartId()) ) ) } else { response.unauthorized() }}
  14. 14. synchronous I/0function productsInCart(request, response) { var db = new Db() var user = new User(request) if (user.isAuthorized("cart/products")) { response.write( JSON.stringify( db.productsInCart(user.cartId()) ) ) } else { response.unauthorized() }}
  15. 15. synchronous I/0function productsInCart(request, response) { var db = new Db() var user = new User(request) if (user.isAuthorized("cart/products")) { response.write( JSON.stringify( db.productsInCart(user.cartId()) ) ) } else { response.unauthorized() }}
  16. 16. synchronous I/0function productsInCart(request, response) { var db = new Db() var user = new User(request) if (user.isAuthorized("cart/products")) { response.write( JSON.stringify( db.productsInCart(user.cartId()) ) ) } else { response.unauthorized() }}
  17. 17. single threadasynchronous I/0
  18. 18. single threadasynchronous I/0 I am “callback” call me if you need me...
  19. 19. hello_world_server.js Event Emitter var http = require("http") var server = http.createServer(function(request, response) { response.writeHead(200, { "Content-Type": "plain/text" }) response.write("Hello Worldn") response.end() }) server.listen(8080) console.log("> SERVER STARTED")
  20. 20. hello_world_server.js Event Emitter var http = require("http") var server = http.createServer(function(request, response) { response.writeHead(200, { "Content-Type": "plain/text" }) response.write("Hello Worldn") response.end() }) server.listen(8080) console.log("> SERVER STARTED")
  21. 21. hello_world_server.js Event Emitter var http = require("http") var server = http.createServer(function(request, response) { response.writeHead(200, { "Content-Type": "plain/text" }) response.write("Hello Worldn") response.end() }) server.listen(8080) console.log("> SERVER STARTED")
  22. 22. hello_world_server.js Event Emitter var http = require("http") var server = http.createServer(function(request, response) { response.writeHead(200, { "Content-Type": "plain/text" }) response.write("Hello Worldn") response.end() }) server.listen(8080) console.log("> SERVER STARTED")
  23. 23. Event Emittercoder@apollo:~/Work/src/node/examples$ node hello_world_server.js> SERVER STARTED #1coder@apollo:~$ curl "http://localhost:8080/"Hello World #2
  24. 24. Event Emitter var server = require("http").createServer()hello_world_server.js server.on("request", function(request, response) { console.log("> REQUEST STARTED") request.on("end", function() { console.log("> REQUEST CLOSED") response.writeHead(200, { "Content-Type": "plain/text" }) response.end("Hello Worldn") server.close() }) response.on("close", function() { console.log("> RESPONSE CLOSED") }) })
  25. 25. hello_world_server.js Event Emitter ... server.on("close", function() { console.log("> SERVER CLOSED") }) server.on("listening", function() { console.log("> SERVER STARTED") }) server.listen(8080)
  26. 26. Event Emittercoder@apollo:~/Work/src/node/examples$ node hello_world_server.js> SERVER STARTED #1coder@apollo:~$ curl "http://localhost:8080/"Hello World #2 #1> REQUEST STARTED> REQUEST CLOSED> SERVER CLOSED
  27. 27. why socomplicated?
  28. 28. data streamS server.on("request", function(request, response) { var chunks = [], output = fs.createWriteStream("./output")proxy_stream.js request.on("data", function(chunk) { chunks = forEachLine(chunks.concat(chunk), function(line) { output.write(parseInt(line, 10) * 2) output.write("n") }) }) request.on("end", function() { response.writeHead(200, { "Content-Type": "plain/text" }) response.end("OKn") output.end() server.close() }) })
  29. 29. data streamScoder@apollo:~/Work/src/node/examples$ node stream_doubler.js #1coder@apollo:~$ curl "http://localhost:8080/" --data $1n2n3nOK #2coder@apollo:~/Work/src/node/examples$ cat output246 #1
  30. 30. why javascript?• Friendly callbacks• ubiquitous (well known)• no I/o primitives• one language to rule them all
  31. 31. web applications before: a webmind shift #1 server with some application logic application Web server application application application
  32. 32. web applications after: an applicationmind shift #1 accessible over http web server application
  33. 33. web applications after: an applicationmind shift #1 that can communicate and collaborate with the world web server application
  34. 34. web applications before: statefulmind shift #2 • no easy to scale • no easy to reuse v M c
  35. 35. web applications before: statefulmind shift #2 • no easy to scale • no easy to reuse v M c conversation application state state
  36. 36. web applications before: statefulmind shift #2 • no easy to scale • no easy to reuse v M c tightly coupled
  37. 37. web applications after: statelessmind shift #2 • easy to scale • easy to reuse v http M c
  38. 38. web applications after: statelessmind shift #2 • easy to scale • easy to reuse v http M cconversation application state state
  39. 39. web applications after: statelessmind shift #2 http web server M http statefull connection• easy to scale M• easy to reuse
  40. 40. no fluffjust stuff
  41. 41. What aboutcpu bound tasks?
  42. 42. the forklong_running_job.sh be with you #!/bin/bash for count in `seq 1 100`; do echo $count sleep 0.1 done
  43. 43. the forklong_running_server.js be with you var spawn = require("child_process").spawn, server = require("http").createServer() server.on("request", function(request, response) { var job = spawn("./long_running_job.sh") job.stdout.on("data", function(tick) { response.write(tick) }) job.on("exit", function() { response.end() }) })
  44. 44. the fork be with youcoder@apollo:~$ ab -c 1 -n 1 "http://localhost:8080/"...Concurrency Level: 1Time taken for tests: 10.531 seconds...coder@apollo:~$ ab -c 1 -n 2 "http://localhost:8080/"...Concurrency Level: 1Time taken for tests: 20.108 seconds...
  45. 45. the fork be with youcoder@apollo:~$ ab -c 2 -n 1 "http://localhost:8080/"...Concurrency Level: 2Time taken for tests: 10.634 seconds...coder@apollo:~$ ab -c 100 -n 100 "http://localhost:8080/"...Concurrency Level: 100Time taken for tests: 11.198 seconds...coder@apollo:~$ ab -c 500 -n 500 "http://localhost:8080/"...Concurrency Level: 500Time taken for tests: 31.082 seconds...
  46. 46. enter cometw at chwatch M spawn ch atw watch w w t a at ch ch
  47. 47. enter cometdemo
  48. 48. INSTALL NPM (node packet manager)coder@apollo:~/Work/src/node/examples$ curl http://npmjs.org/install.sh | sh...npm okIt workedcoder@apollo:~/Work/src/node/examples$ npm search | wc -l1918coder@apollo:~/Work/src/node/examples$ npm install connect socket.io underscorecoder@apollo:~/Work/src/node/examples$ npm list!"# connect@1.4.1$ !"" mime@1.2.2$ %"" qs@0.1.0%"" socket.io@0.6.17%"" underscore@1.1.6
  49. 49. server/ routingprogress_server.js var server = connect( connect.favicon(), connect.logger({"buffer": true}), connect.router(function(resource) { resource.post("/spawn", function(request, response) { ... }) }), connect.static(path.join(__dirname, "public"), {"cache": true}) )
  50. 50. server/ routingprogress_server.js resource.post("/spawn", function(request, response) { var job = spawn(path.join(__dirname, "bin", "job.sh")), id = ++counter response.writeHead(202, {"Content-Type": "plain/text"}) response.end("OKn") job.stdout.on("data", function(output) { var progress = parseInt(output.toString(), 10) _(connections).each(function(connection) { connection.send({"id": id, "progress": progress}) }) }) })
  51. 51. server/ socket.ioprogress_server.js io.listen(server).on("connection", function(client) { connections[client.sessionId] = client client.on("disconnect", function() { delete connections[client.sessionId] }) })
  52. 52. server/ simulationprogress_server.js server.listen(port, host, function() { var spawnJobsInterval = setInterval(function() { http.request({ "port": port, "host": host, "method": "POST", "path": "/spawn" }).end() }, Math.floor(Math.random()*2000)+500) server.on("close", function() { clearInterval(spawnJobsInterval) process.exit() }) }) process.on("SIGINT", function() { server.close() })
  53. 53. interface/html <html> <head> <title>Node.js - Long Running Jobs</title> <link href="css/style.css" rel="stylesheet" /> <script type="text/javascript" src="/socket.io/socket.io.js"></script> <script type="text/javascript" src="js/jquery-1.6.0.js"></script> <script type="text/javascript" src="js/progress.js"></script>index.html </head> <body> <div id="template"> <div class="progress-container"> <span class="progress-text">JOB/? - ?%</span> <div class="progress-bar"></div> </div> </div> <div id="container"> </div> </body> <script> ... </script> </html>
  54. 54. interface/ socket.io <html> ... <script> $(function() { var socket = new io.Socket()index.html socket.on("connect", function() { }) socket.on("disconnect", function() { }) socket.on("message", function(job) { $("#template").progressBar(job.id, job.progress) }) socket.connect() }) </script> </html>
  55. 55. interface/ progress bar $.fn.progressBar = function(id, progress) { var $template = $(this) $("#job-" + id) .otherwise(function() { return $template.children().clone()progress.js .attr("id", "job-" + id) .find(".progress-text").text("JOB/" + id + " - 0%").end() .appendTo("#container") }) .find(".progress-text").text("JOB/" + id + " - " + progress + "%").end() .find(".progress-bar").css("width", progress + "%").end() .tap(function() { if (progress === 100) { $(this) .find(".progress-bar").css("background-color", "red").end() .after(500, function() { $(this).fadeOut("slow", function() { $(this).remove() }) }) }
  56. 56. interface/ progress bar $.fn.otherwise = function(ifNotFound) { if (this.length === 0) { return ifNotFound() }progress.js return this } $.fn.after = function(milliseconds, doSomething) { var self = this setTimeout(function() { doSomething.apply(self) }, milliseconds) return this } $.fn.tap = function() { var fn = Array.prototype.shift.apply(arguments) fn.apply(this, arguments) return this }
  57. 57. we can do itwith a littlemore “style”
  58. 58. server/ event emitter var Job = (function() { var EventEmitter = require("events").EventEmitter,progress_server.js spawn = require("child_process").spawn, inherits = require("util").inherits function Job(id) { EventEmitter.call(this) this.id = id } inherits(Job, EventEmitter) Job.prototype.run = function() { return _(this).tap(function(job) { spawn(path.join(__dirname, "bin", "job.sh")) .stdout.on("data", function(output) { job.emit("progress", job.id, parseInt(output.toString(), 10)) }) }) } return Job })()
  59. 59. server/ event emitterprogress_server.js resource.post("/spawn", function(request, response) { new Job(++counter) .on("progress", function(id, progress) { _(connections).each(function(connection) { connection.send({"id": id, "progress": progress}) }) }) .run() response.writeHead(202, { "Content-Type": "plain/text" }) response.end("OKn") })
  60. 60. node.js is awesome but when should i use it?
  61. 61. when to use it?• chat/messaging• real-time applications• intelligent proxies• high concurrency applications• communication hubs• coordinators
  62. 62. please tellme something bad about node.js
  63. 63. some warnings• release stable 0.4.7 (young)• lots of stuffs to look at• lots of half backed stuffs• retro compatibility???• bad at handling static contents• Bad at handling binary contents• hard to find organized and authoritative informations
  64. 64. vs
  65. 65. Questions?
  66. 66. gabriele lana gabriele.lana@cleancode.it twitter: @gabrielelanahttp://joind.in/3359
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×