Node.js Dojo

21,079 views

Published on

Introduction to Node.js for Grenoble JavaScript User Group

Published in: Technology, Business
1 Comment
2 Likes
Statistics
Notes
No Downloads
Views
Total views
21,079
On SlideShare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
38
Comments
1
Likes
2
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Node.js Dojo

    1. 1. Node.jsGrenoble JS - 2011/10/19
    2. 2. Who am I?
    3. 3. Who am I?Jeff Mesnil
    4. 4. Who am I?Jeff MesnilSoftware Developer at Bestofmedia
    5. 5. Who am I?Jeff MesnilSoftware Developer at Bestofmediahttp://jmesnil.net/
    6. 6. Who am I?Jeff MesnilSoftware Developer at Bestofmediahttp://jmesnil.net/jmesnil@gmail.com
    7. 7. Who am I?Jeff MesnilSoftware Developer at Bestofmediahttp://jmesnil.net/jmesnil@gmail.comtwitter: @jmesnil
    8. 8. Previously
    9. 9. PreviouslyRed Hat / JBoss
    10. 10. PreviouslyRed Hat / JBossHornetQ messaging server
    11. 11. PreviouslyRed Hat / JBossHornetQ messaging serverWritten in Java
    12. 12. PreviouslyRed Hat / JBossHornetQ messaging serverWritten in JavaConcurrency
    13. 13. PreviouslyRed Hat / JBossHornetQ messaging serverWritten in JavaConcurrencyThousands of producers/consumers
    14. 14. PreviouslyRed Hat / JBossHornetQ messaging serverWritten in JavaConcurrencyThousands of producers/consumersHard to write correct multithreaded code
    15. 15. PreviouslyRed Hat / JBossHornetQ messaging serverWritten in JavaConcurrencyThousands of producers/consumersHard to write correct multithreaded codeImpossible to prove it is correct
    16. 16. «Ive learned that you can never believe that a program using shared-memory concurrency (which is what threading uses) is working correctly - You can only discover that its wrong, but you can never prove that its right. ... you can never let yourself become too confident about your programming abilities when it comes to shared-memory concurrency. I would not besurprised if, sometime in the future, someone comes up with a proof to show that shared-memory concurrency programming is only possible in theory, but not in practice.» -- Bruce Eckel, Thinking in Java
    17. 17. Multithreading is Hard Let’s Go Shopping!
    18. 18. • Erlang, Scala
    19. 19. • Erlang, Scala • Actor Model
    20. 20. • Erlang, Scala • Actor Model• Clojure
    21. 21. • Erlang, Scala • Actor Model• Clojure • Software Transaction Model (STM)
    22. 22. node.js ?
    23. 23. http://nodejs.org/
    24. 24. Evented I/O for V8 JavaScript
    25. 25. V8
    26. 26. V8From Google
    27. 27. V8From GoogleOpen Source JavaScript engine
    28. 28. V8From GoogleOpen Source JavaScript engineUsed in Google Chrome
    29. 29. V8From GoogleOpen Source JavaScript engineUsed in Google ChromeStandalone or embedded into any C++application
    30. 30. V8From GoogleOpen Source JavaScript engineUsed in Google ChromeStandalone or embedded into any C++applicationFast (for a JavaScript Engine...)
    31. 31. JavaScript
    32. 32. JavaScriptNode applications are written in JavaScript(or CoffeeScript...)
    33. 33. JavaScriptNode applications are written in JavaScript(or CoffeeScript...)Functions are 1st-class citizen
    34. 34. JavaScriptNode applications are written in JavaScript(or CoffeeScript...)Functions are 1st-class citizenWell suited for event-driven applications
    35. 35. JavaScriptNode applications are written in JavaScript(or CoffeeScript...)Functions are 1st-class citizenWell suited for event-driven applicationsNo standard I/O library...
    36. 36. Event Loopwhile (true) ready_channels = select(io_channels) for channel in ready_channels performIO(channel)
    37. 37. Single thread (on a single core)
    38. 38. Single thread (on a single core)Register interested I/O events and a callback
    39. 39. Single thread (on a single core)Register interested I/O events and a callbackCalled back when the event occurs
    40. 40. Asynchronous I/O
    41. 41. Read a Filevar fs = require(fs);fs.readFile(/usr/share/dict/words, utf8, function (err, data) { if (err) throw err; console.log(data);});
    42. 42. TCP Echo Servervar net = require(net);var server = net.createServer(function (socket) {  socket.setEncoding(utf-8);  socket.write("Echo serverrn");  socket.on(data, function(data) {    console.log(data);    socket.write(data.toUpperCase());  });});server.listen(1337, "127.0.0.1");
    43. 43. $ telnet localhost 1337Echo serverhello, World!!HELLO, WORLD!!
    44. 44. node.js is good for
    45. 45. node.js is good for• I/O-bound Code
    46. 46. node.js is good for• I/O-bound Code • DB, Web Services connectivity
    47. 47. node.js is good for• I/O-bound Code • DB, Web Services connectivity • Data Aggregation
    48. 48. node.js is good for• I/O-bound Code • DB, Web Services connectivity • Data Aggregation • Non-blocking communication
    49. 49. node.js is good for• I/O-bound Code • DB, Web Services connectivity • Data Aggregation • Non-blocking communication• Do a bit of I/O and let the others play
    50. 50. node.js is not good for
    51. 51. node.js is not good for• CPU-bound applications
    52. 52. node.js is not good for• CPU-bound applications • Computation (Fibonacci...)
    53. 53. node.js is not good for• CPU-bound applications • Computation (Fibonacci...) • Machine-Learning algorithm
    54. 54. node.js is not good for• CPU-bound applications • Computation (Fibonacci...) • Machine-Learning algorithm • ...
    55. 55. node.js is not good for• CPU-bound applications • Computation (Fibonacci...) • Machine-Learning algorithm • ...• Everybody has to wait its turn
    56. 56. Workaround is to start new processes viachild_process.fork()
    57. 57. Workaround is to start new processes viachild_process.fork()Data communication?
    58. 58. Workaround is to start new processes viachild_process.fork()Data communication?Load?
    59. 59. Workaround is to start new processes viachild_process.fork()Data communication?Load?Web Workers API (or Isolates à la Dart)?
    60. 60. Google Scraper
    61. 61. Google Scraper• For a query
    62. 62. Google Scraper• For a query • Connect to Google and fetch a result page
    63. 63. Google Scraper• For a query • Connect to Google and fetch a result page • Use JQuery to find all the anchors for the results
    64. 64. Google Scraper• For a query • Connect to Google and fetch a result page • Use JQuery to find all the anchors for the results • Print their URLs
    65. 65. $ node scraper.js "node javascript"http://nodejs.org/http://www.theregister.co.uk/2011/03/01/the_rise_and_rise_of_node_dot_js/http://www.howtocreate.co.uk/tutorials/javascript/dombasicshttp://net.tutsplus.com/tutorials/javascript-ajax/learning-serverside-javascript-with-node-js/...
    66. 66. var request = require(request),    jsdom = require(jsdom);var args = process.argv.slice(2);if (args.length != 1) {  console.log(Usage: node scraper.js <query sentence>);  process.exit(1);}var query = escape(args[0]);var url = http://www.google.fr/search?hl=fr&source=hp&ie=ISO-8859-1&q= + query + &btnG=Recherche+Googlerequest({ uri: url }, function (error, response, body) {  if (error) {    console.log(Error when contacting google.com: + error);    process.exit(2);  }  if (response && response.statusCode !== 200) {    console.log(Did not get a correct response from Google: + response);    process.exit(2);  }  jsdom.env({    html: body,    scripts: [      http://code.jquery.com/jquery-1.5.min.js    ]  }, function (err, window) {    var $ = window.jQuery;    $(a.l).each(function() {      console.log($(this).attr(href));    });  });
    67. 67. var request = require(request),    jsdom = require(jsdom);var args = process.argv.slice(2); ica tionif (args.length != 1) { a ppl  console.log(Usage: node scraper.js <query sentence>); p the u  process.exit(1); set}var query = escape(args[0]);var url = http://www.google.fr/search?hl=fr&source=hp&ie=ISO-8859-1&q= + query + &btnG=Recherche+Googlerequest({ uri: url }, function (error, response, body) {  if (error) {    console.log(Error when contacting google.com: + error);    process.exit(2);  }  if (response && response.statusCode !== 200) {    console.log(Did not get a correct response from Google: + response);    process.exit(2);  }  jsdom.env({    html: body,    scripts: [      http://code.jquery.com/jquery-1.5.min.js    ]  }, function (err, window) {    var $ = window.jQuery;    $(a.l).each(function() {      console.log($(this).attr(href));    });  });
    68. 68. var request = require(request),    jsdom = require(jsdom);var args = process.argv.slice(2); ica tionif (args.length != 1) { a ppl  console.log(Usage: node scraper.js <query sentence>); p the u  process.exit(1); set}var query = escape(args[0]);var url = http://www.google.fr/search?hl=fr&source=hp&ie=ISO-8859-1&q= + query + &btnG=Recherche+Googlerequest({ uri: url }, function (error, response, body) {  if (error) {    console.log(Error when contacting google.com: + error);    process.exit(2);  }  if (response && response.statusCode !== 200) {    console.log(Did not get a correct response from Google: + response); es ults    process.exit(2); og le r  } h Go  jsdom.env({ fetc    html: body,    scripts: [      http://code.jquery.com/jquery-1.5.min.js    ]  }, function (err, window) {    var $ = window.jQuery;    $(a.l).each(function() {      console.log($(this).attr(href));    });  });
    69. 69. var request = require(request),    jsdom = require(jsdom);var args = process.argv.slice(2); ica tionif (args.length != 1) { a ppl  console.log(Usage: node scraper.js <query sentence>); p the u  process.exit(1); set}var query = escape(args[0]);var url = http://www.google.fr/search?hl=fr&source=hp&ie=ISO-8859-1&q= + query + &btnG=Recherche+Googlerequest({ uri: url }, function (error, response, body) {  if (error) {    console.log(Error when contacting google.com: + error);    process.exit(2);  }  if (response && response.statusCode !== 200) {    console.log(Did not get a correct response from Google: + response); es ults    process.exit(2); og le r  } h Go  jsdom.env({ fetc y    html: body, JQ uer h wit    scripts: [ rs cho      http://code.jquery.com/jquery-1.5.min.js an the    ]  }, function (err, window) { find    var $ = window.jQuery;    $(a.l).each(function() {      console.log($(this).attr(href));    });  });
    70. 70. var request = require(request),    jsdom = require(jsdom);var args = process.argv.slice(2); ica tionif (args.length != 1) { a ppl  console.log(Usage: node scraper.js <query sentence>); p the u  process.exit(1); set}var query = escape(args[0]);var url = http://www.google.fr/search?hl=fr&source=hp&ie=ISO-8859-1&q= + query + &btnG=Recherche+Googlerequest({ uri: url }, function (error, response, body) {  if (error) {    console.log(Error when contacting google.com: + error);    process.exit(2);  }  if (response && response.statusCode !== 200) {    console.log(Did not get a correct response from Google: + response); es ults    process.exit(2); og le r  } h Go  jsdom.env({ fetc y    html: body, JQ uer h wit    scripts: [ rs cho      http://code.jquery.com/jquery-1.5.min.js an s the URL    ]  }, function (err, window) { find eir t th prin    var $ = window.jQuery;    $(a.l).each(function() {      console.log($(this).attr(href));    });  });
    71. 71. // Node.js modules required to run the scraper// use npm to install them:// $ `curl http://npmjs.org/install.sh | sh`var request = require(request),    jsdom = require(jsdom);
    72. 72. // Node.js modules required to run the scraper// use npm to install them:// $ `curl http://npmjs.org/install.sh | sh` ap per wr u est P reqvar request = require(request), HTT    jsdom = require(jsdom);
    73. 73. // Node.js modules required to run the scraper// use npm to install them:// $ `curl http://npmjs.org/install.sh | sh` per w rap u est ver req Ser TTP thevar request = require(request), H yo n Q uer u se j    jsdom = require(jsdom);
    74. 74. // remove node and the file name from the arguments listvar args = process.argv.slice(2);if (args.length != 1) {  console.log(Usage: node scraper.js <query sentence>);  process.exit(1);}// the query to search on Googlevar query = escape(args[0]);// Google URL that will be request and whose content will be scrapedvar url = http://www.google.com/search?q= + query;
    75. 75. request({ uri: url }, function (error, response, body) {  // nothing to do if we get an error from Google  if (error) {    console.log(Error when contacting google.com: + error);    process.exit(2);  }  // idem if the response is not OK  if (response && response.statusCode !== 200) {    console.log(Did not get a correct response from Google: + response);    process.exit(2);  } ...});
    76. 76. po nserequest({ uri: url }, function (error, response, body) { a res e get w  // nothing to do if we get an error from Google w hen b ack  if (error) { call    console.log(Error when contacting google.com: + error);    process.exit(2);  }  // idem if the response is not OK  if (response && response.statusCode !== 200) {    console.log(Did not get a correct response from Google: + response);    process.exit(2);  } ...});
    77. 77. po nserequest({ uri: url }, function (error, response, body) { a res e get w  // nothing to do if we get an error from Google w hen b ack  if (error) { call    console.log(Error when contacting google.com: + error);    process.exit(2);  }  // idem if the response is not OK  if (response && response.statusCode !== 200) {    console.log(Did not get a correct response from Google: + response);    process.exit(2);  } b ody in the li nks the find et’s ... l});
    78. 78. // use jsdom and jQuery to manipulate the DOM corresponding to the responses body  jsdom.env({    html: body,    scripts: [       // jQuery is loaded directly from its web site.       // We could instead cache it locally for efficiency      http://code.jquery.com/jquery-1.5.min.js    ]  }, function (err, window) { ...  });
    79. 79. // use jsdom and jQuery to manipulate the DOM corresponding to the responses body y  jsdom.env({ jQ uer up o set    html: body, do mt s    scripts: [ use j       // jQuery is loaded directly from its web site.       // We could instead cache it locally for efficiency      http://code.jquery.com/jquery-1.5.min.js    ]  }, function (err, window) { ...  });
    80. 80. // use jsdom and jQuery to manipulate the DOM corresponding to the responses body y  jsdom.env({ jQ uer up o set    html: body, do mt s    scripts: [ use j       // jQuery is loaded directly from its web site.       // We could instead cache it locally for efficiency      http://code.jquery.com/jquery-1.5.min.js    ]  }, function (err, window) { yc ode uer ... iliar jQ m oe s fa  }); he re g
    81. 81. // alias jQuery object to the more familiar $var $ = window.jQuery;  // print the URLS of the results listed by Google...    $(a.l).each(function() {      console.log($(this).attr(href));    });
    82. 82. Russian Dolls
    83. 83. Spaghetti Code?
    84. 84. No Silver Bullet...
    85. 85. Another arrow in your quiver!
    86. 86. «Ruby, Javascript, and Clojure are all general-purpose languages, but they each excel at certain use cases. Rubys highly dynamic nature and emphasis on beauty makes it a natural fit for user-facing web apps. Node.jss evented concurrency makes it a great fit for the realtimeweb. Clojure covers a new use case on the Heroku platform: components which demand correctness, performance,composability; and optionally, access to the Java ecosystem.» -- http://blog.heroku.com/archives/2011/7/5/ clojure_on_heroku
    87. 87. https://github.com/jmesnil/node-sampleshttps://groups.google.com/forum/?hl=fr#!forum/grenoblejs
    88. 88. Questions?
    89. 89. Thanks!

    ×