Node.js:                         Asynchronous I/O for                            Fun and Pro t                           S...
Stefan Tilkov                                  @stilkov                         stefan.tilkov@innoq.com                   ...
Concurrent Request ProcessingFriday, March 11, 2011
Friday, March 11, 2011
Friday, March 11, 2011
Friday, March 11, 2011
Friday, March 11, 2011
Friday, March 11, 2011
Friday, March 11, 2011
read requestFriday, March 11, 2011
read request                         parse requestFriday, March 11, 2011
read request                         parse request                            processFriday, March 11, 2011
read request                            parse request                               process                         send b...
read request                            parse request                               process                         send b...
read request                            parse request                               process                         send b...
read request                            parse request                               process                         send b...
read request                            parse request                               process                         send b...
read request                            parse request                               process                         send b...
Blocking I/O ProblemsFriday, March 11, 2011
Blocking I/O Problems                             Thread starvationFriday, March 11, 2011
Blocking I/O Problems                             Thread starvation                            Memory utilizationFriday, M...
Blocking I/O Problems                             Thread starvation                            Memory utilization         ...
Blocking I/O Problems                             Thread starvation                            Memory utilization         ...
Blocking I/O Problems                             Thread starvation                            Memory utilization         ...
User                                  Space                         KernelFriday, March 11, 2011
Event Loop                         while (true)                           ready_channels = select(io_channels)            ...
Async I/O CharacteristicsFriday, March 11, 2011
Async I/O Characteristics                            Program always runningFriday, March 11, 2011
Async I/O Characteristics                            Program always running                           I/O-bound calls neve...
Async I/O Characteristics                            Program always running                           I/O-bound calls neve...
Async I/O Characteristics                            Program always running                           I/O-bound calls neve...
Async I/O Characteristics                              Program always running                            I/O-bound calls n...
requests/second     http://blog.webfaction.com/a-little-holiday-presentFriday, March 11, 2011
memory     http://blog.webfaction.com/a-little-holiday-presentFriday, March 11, 2011
/dev/poll                         select()                                                 aio_*()                        ...
java.nio                         .NET I/O Completion PortsFriday, March 11, 2011
Async I/O PerceptionFriday, March 11, 2011
Async I/O Perception                            Not widely knownFriday, March 11, 2011
Async I/O Perception                            Not widely known                               Low levelFriday, March 11, ...
Async I/O Perception                            Not widely known                                Low level                 ...
Async I/O Perception                             Not widely known                                 Low level               ...
JavaScriptFriday, March 11, 2011
JavaScript PerceptionFriday, March 11, 2011
JavaScript Perception                             “Toy language”Friday, March 11, 2011
JavaScript Perception                             “Toy language”                              IncompatibleFriday, March 11...
JavaScript Perception                             “Toy language”                              Incompatible                ...
JavaScript Perception                             “Toy language”                              Incompatible                ...
http://commons.wikimedia.org/wiki/File:Audi_S5_V8_FSI_engine.jpgFriday, March 11, 2011
Friday, March 11, 2011
http://commons.wikimedia.org/wiki/File:Ateles_paniscus_-Brazil-8.jpgFriday, March 11, 2011
Friday, March 11, 2011
The JavaScript Arms RaceFriday, March 11, 2011
Friday, March 11, 2011
Friday, March 11, 2011
http://oreilly.com/catalog/9780596517748Friday, March 11, 2011
Friday, March 11, 2011
JavaScript TodayFriday, March 11, 2011
JavaScript Today                         Popular & widely usedFriday, March 11, 2011
JavaScript Today                         Popular & widely used                           O en mandatoryFriday, March 11, 2...
JavaScript Today                         Popular & widely used                           O en mandatory                   ...
JavaScript Today                         Popular & widely used                           O en mandatory                   ...
JavaScript Today                         Popular & widely used                           O en mandatory                   ...
Node.jsFriday, March 11, 2011
Node.js Architecture                         v8    libev   libeio   http_parser   c_aresFriday, March 11, 2011
Node.js Architecture                                Network/Platform layer (C)                         v8    libev     lib...
Node.js Architecture                                       API (JavaScript)                                Network/Platfor...
High-performance network                    runtime, using JavaScript as                          a high-level DSLFriday, ...
var net = require(net);                     var server = net.createServer(function (socket) {                        socke...
var net = require(net);                     var server = net.createServer(function (socket) {                       socket...
var sys = require("sys"), http = require("http"), url = require("url"),         path = require("path"), fs = require("fs")...
Concurrency Level:      100               Time taken for tests:   6.000 seconds               Complete requests:      1000...
http.createServer(function(request, response) {             var uri = url.parse(request.url).pathname;             var fil...
HTTP ChunkingFriday, March 11, 2011
HTTP/1.0                            connect                  Client              ServerFriday, March 11, 2011
HTTP/1.0                             connect                           send request                  Client               ...
HTTP/1.0                              connect                            send request                           send respo...
HTTP/1.0                               connect                             send request                            send re...
HTTP/1.0                               connect                             send request                            send re...
HTTP/1.0                               connect                             send request                            send re...
HTTP/1.0                                connect                              send request                             send...
HTTP/1.0                                connect                              send request                             send...
HTTP/1.0                                connect                              send request                             send...
HTTP/1.0                                connect                              send request                             send...
HTTP/1.1: Content-length                  Client                              ServerFriday, March 11, 2011
HTTP/1.1: Content-length                                    connect                  Client                              S...
HTTP/1.1: Content-length                                    connect                               Connection: keep-alive  ...
HTTP/1.1: Content-length                                    connect                               Connection: keep-alive  ...
HTTP/1.1: Content-length                                    connect                               Connection: keep-alive  ...
HTTP/1.1: Content-length                                    connect                               Connection: keep-alive  ...
HTTP/1.1: Content-length                                    connect                               Connection: keep-alive  ...
HTTP/1.1: Content-length                                    connect                               Connection: keep-alive  ...
HTTP/1.1: Content-length                                    connect                               Connection: keep-alive  ...
HTTP/1.1: Content-length                                    connect                               Connection: keep-alive  ...
HTTP/1.1: Content-length                                    connect                               Connection: keep-alive  ...
HTTP/1.1: Transfer-encoding: chunked                  Client                   ServerFriday, March 11, 2011
HTTP/1.1: Transfer-encoding: chunked                                connect                           Connection: keep-ali...
HTTP/1.1: Transfer-encoding: chunked                                connect                           Connection: keep-ali...
HTTP/1.1: Transfer-encoding: chunked                                connect                           Connection: keep-ali...
HTTP/1.1: Transfer-encoding: chunked                                    connect                             Connection: ke...
HTTP/1.1: Transfer-encoding: chunked                                    connect                             Connection: ke...
HTTP/1.1: Transfer-encoding: chunked                                    connect                             Connection: ke...
HTTP/1.1: Transfer-encoding: chunked                                    connect                             Connection: ke...
HTTP/1.1: Transfer-encoding: chunked                                    connect                             Connection: ke...
http.createServer(function(request, response) {                       var uri = url.parse(request.url).pathname;          ...
var hashFile = function(filename, cb) {           path.exists(filename, function(exists) {             if(exists) {       ...
var options = function(request) {          // ...        }        http.createServer(function(request, response) {         ...
http.createServer(function(request, response) {    sys.log("--> " + request.url);    var remoteRequest = http.request(opti...
Asynchronous                         Programming                          ChallengesFriday, March 11, 2011
or:                          Why Programming                         with Callbacks SucksFriday, March 11, 2011
Friday, March 11, 2011
var bold = function(text) {                 return text.bold();              };              var capitalize = function(tex...
var boldAsync = function(text, callback) {     setTimeout(function (text) {       callback(text.bold());     }, 100, text)...
var boldAsync = function(text, callback) {     setTimeout(function (text) {       callback(text.bold());     }, 100, text)...
try {            console.log("Synchronous:");            var result1 = capitalize(null);            var result2 = bold(res...
try {                console.log("Asynchronous:");                capitalizeAsync(text, function(result1) {               ...
// bad, dont do this              try {                console.log("Asynchronous:");                capitalizeAsync(text, ...
var boldAsync = function(text, callback) {             setTimeout(function (text) {               try {                 ca...
capitalizeAsync(text, function(err, result1) {               if (!err) {                 boldAsync(result1, function(err, ...
var handleError = function(err, fn) {                    if (err) {                      console.log("Handling async error...
var step = require("step");         step(            function () {               capitalizeAsync(text, this);            }...
var words = [one, two, three, four, five];               var upcasedWords = [];               words.forEach(function (word...
var words = [one, two, three, four, five];               var upcasedWords = [];               // bad, dont do this        ...
var count = words.length;                words.forEach(function (word) {                  capitalize(word, function(err, w...
var words = [one, two, three, four, five];  step(    function () {       var i, length;       for (i = 0, length = words.l...
Tools & EcosystemFriday, March 11, 2011
Friday, March 11, 2011
npm                 node package manager            Connect             Asynchronous, low-level HTTP handler              ...
var multi = require("multi-node");       var server = http.createServer(function(request, response) {         var uri = ur...
SummaryFriday, March 11, 2011
Node.js popularizes                          the “right way”                     of network programmingFriday, March 11, 2...
JavaScript doesn’t suck                      as much as you thinkFriday, March 11, 2011
There’s a smart and                          active communityFriday, March 11, 2011
Node.js is fun to use!Friday, March 11, 2011
Thank you!                         Q&AFriday, March 11, 2011
Upcoming SlideShare
Loading in...5
×

Node.js: Asynchronous I/O for Fun and Profit

1,606

Published on

http://www.infoq.com/presentations/Nodejs-Asynchronous-IO-for-Fun-and-Profit

Published in: Technology, News & Politics
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,606
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
30
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

Node.js: Asynchronous I/O for Fun and Profit

  1. 1. Node.js: Asynchronous I/O for Fun and Pro t Stefan Tilkov @ QCon London 2011Friday, March 11, 2011
  2. 2. Stefan Tilkov @stilkov stefan.tilkov@innoq.com http://www.innoq.comFriday, March 11, 2011
  3. 3. Concurrent Request ProcessingFriday, March 11, 2011
  4. 4. Friday, March 11, 2011
  5. 5. Friday, March 11, 2011
  6. 6. Friday, March 11, 2011
  7. 7. Friday, March 11, 2011
  8. 8. Friday, March 11, 2011
  9. 9. Friday, March 11, 2011
  10. 10. read requestFriday, March 11, 2011
  11. 11. read request parse requestFriday, March 11, 2011
  12. 12. read request parse request processFriday, March 11, 2011
  13. 13. read request parse request process send backend requestFriday, March 11, 2011
  14. 14. read request parse request process send backend request read backend answerFriday, March 11, 2011
  15. 15. read request parse request process send backend request read backend answer processFriday, March 11, 2011
  16. 16. read request parse request process send backend request read backend answer process format responseFriday, March 11, 2011
  17. 17. read request parse request process send backend request read backend answer process format response send responseFriday, March 11, 2011
  18. 18. read request parse request process send backend request read backend answer process format response send responseFriday, March 11, 2011
  19. 19. Blocking I/O ProblemsFriday, March 11, 2011
  20. 20. Blocking I/O Problems Thread starvationFriday, March 11, 2011
  21. 21. Blocking I/O Problems Thread starvation Memory utilizationFriday, March 11, 2011
  22. 22. Blocking I/O Problems Thread starvation Memory utilization External dependenciesFriday, March 11, 2011
  23. 23. Blocking I/O Problems Thread starvation Memory utilization External dependencies Cascading problemsFriday, March 11, 2011
  24. 24. Blocking I/O Problems Thread starvation Memory utilization External dependencies Cascading problems Non-streaming approachFriday, March 11, 2011
  25. 25. User Space KernelFriday, March 11, 2011
  26. 26. Event Loop while (true) ready_channels = select(io_channels) for (channel in ready_channels) performIO(channel)Friday, March 11, 2011
  27. 27. Async I/O CharacteristicsFriday, March 11, 2011
  28. 28. Async I/O Characteristics Program always runningFriday, March 11, 2011
  29. 29. Async I/O Characteristics Program always running I/O-bound calls never blockFriday, March 11, 2011
  30. 30. Async I/O Characteristics Program always running I/O-bound calls never block Kernel handles I/OFriday, March 11, 2011
  31. 31. Async I/O Characteristics Program always running I/O-bound calls never block Kernel handles I/O Noti cation via eventsFriday, March 11, 2011
  32. 32. Async I/O Characteristics Program always running I/O-bound calls never block Kernel handles I/O Noti cation via events Used for timers, le I/O, net I/O, ...Friday, March 11, 2011
  33. 33. requests/second http://blog.webfaction.com/a-little-holiday-presentFriday, March 11, 2011
  34. 34. memory http://blog.webfaction.com/a-little-holiday-presentFriday, March 11, 2011
  35. 35. /dev/poll select() aio_*() poll() kqueue() epoll()Friday, March 11, 2011
  36. 36. java.nio .NET I/O Completion PortsFriday, March 11, 2011
  37. 37. Async I/O PerceptionFriday, March 11, 2011
  38. 38. Async I/O Perception Not widely knownFriday, March 11, 2011
  39. 39. Async I/O Perception Not widely known Low levelFriday, March 11, 2011
  40. 40. Async I/O Perception Not widely known Low level Hard to useFriday, March 11, 2011
  41. 41. Async I/O Perception Not widely known Low level Hard to use Exception rather than ruleFriday, March 11, 2011
  42. 42. JavaScriptFriday, March 11, 2011
  43. 43. JavaScript PerceptionFriday, March 11, 2011
  44. 44. JavaScript Perception “Toy language”Friday, March 11, 2011
  45. 45. JavaScript Perception “Toy language” IncompatibleFriday, March 11, 2011
  46. 46. JavaScript Perception “Toy language” Incompatible Inherent design problemsFriday, March 11, 2011
  47. 47. JavaScript Perception “Toy language” Incompatible Inherent design problems Low PerformanceFriday, March 11, 2011
  48. 48. http://commons.wikimedia.org/wiki/File:Audi_S5_V8_FSI_engine.jpgFriday, March 11, 2011
  49. 49. Friday, March 11, 2011
  50. 50. http://commons.wikimedia.org/wiki/File:Ateles_paniscus_-Brazil-8.jpgFriday, March 11, 2011
  51. 51. Friday, March 11, 2011
  52. 52. The JavaScript Arms RaceFriday, March 11, 2011
  53. 53. Friday, March 11, 2011
  54. 54. Friday, March 11, 2011
  55. 55. http://oreilly.com/catalog/9780596517748Friday, March 11, 2011
  56. 56. Friday, March 11, 2011
  57. 57. JavaScript TodayFriday, March 11, 2011
  58. 58. JavaScript Today Popular & widely usedFriday, March 11, 2011
  59. 59. JavaScript Today Popular & widely used O en mandatoryFriday, March 11, 2011
  60. 60. JavaScript Today Popular & widely used O en mandatory FastFriday, March 11, 2011
  61. 61. JavaScript Today Popular & widely used O en mandatory Fast CompatibleFriday, March 11, 2011
  62. 62. JavaScript Today Popular & widely used O en mandatory Fast Compatible Best practicesFriday, March 11, 2011
  63. 63. Node.jsFriday, March 11, 2011
  64. 64. Node.js Architecture v8 libev libeio http_parser c_aresFriday, March 11, 2011
  65. 65. Node.js Architecture Network/Platform layer (C) v8 libev libeio http_parser c_aresFriday, March 11, 2011
  66. 66. Node.js Architecture API (JavaScript) Network/Platform layer (C) v8 libev libeio http_parser c_aresFriday, March 11, 2011
  67. 67. High-performance network runtime, using JavaScript as a high-level DSLFriday, March 11, 2011
  68. 68. var net = require(net); var server = net.createServer(function (socket) { socket.write("Echo serverrn"); socket.pipe(socket); }) server.listen(8124, "127.0.0.1"); Code samples: http://github.com/stilkov/node-samples echo.jsFriday, March 11, 2011
  69. 69. var net = require(net); var server = net.createServer(function (socket) { socket.write("Echo serverrn"); socket.setEncoding(ascii); socket.on(data, function(data) { socket.write(data.toUpperCase()); }); }); server.listen(8124, "127.0.0.1"); echo-upcase.jsFriday, March 11, 2011
  70. 70. var sys = require("sys"), http = require("http"), url = require("url"), path = require("path"), fs = require("fs"); var dir = process.argv[2] || ./public; var port = parseFloat(process.argv[3]) || 8080; sys.log(Serving files from + dir + , port is + port); http.createServer(function(request, response) { var uri = url.parse(request.url).pathname; var filename = path.join(process.cwd(), dir, uri); path.exists(filename, function(exists) { if(exists) { fs.readFile(filename, function(err, data) { response.writeHead(200); response.end(data); }); } else { sys.log(File not found: + filename); response.writeHead(404); response.end(); } }); }).listen(port); le-server.jsFriday, March 11, 2011
  71. 71. Concurrency Level: 100 Time taken for tests: 6.000 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Keep-Alive requests: 0 Total transferred: 710781 bytes HTML transferred: 150165 bytes Requests per second: 1666.72 [#/sec] (mean) Time per request: 59.998 [ms] (mean) Time per request: 0.600 [ms] (mean, across all concurrent requests) Transfer rate: 115.69 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 8 8.3 5 57 Processing: 1 51 44.4 40 307 Waiting: 0 43 43.5 30 302 Total: 1 59 44.8 50 316 Percentage of the requests served within a certain time (ms) 50% 50 66% 58 75% 68 80% 73 90% 112 95% 174 98% 206 99% 224 100% 316 (longest request)Friday, March 11, 2011
  72. 72. http.createServer(function(request, response) { var uri = url.parse(request.url).pathname; var filename = path.join(process.cwd(), dir, uri); sys.log(Serving file + filename); path.exists(filename, function(exists) { if(exists) { fs.readFile(filename, function(err, data) { var hash = crypto.createHash(md5); hash.update(data); response.writeHead(200, { Content-Type: text/plain, Content-MD5: hash.digest(base64) } ); response.end(data); }); } else { response.writeHead(404); response.end(); } }); }).listen(port); le-server-md5.jsFriday, March 11, 2011
  73. 73. HTTP ChunkingFriday, March 11, 2011
  74. 74. HTTP/1.0 connect Client ServerFriday, March 11, 2011
  75. 75. HTTP/1.0 connect send request Client ServerFriday, March 11, 2011
  76. 76. HTTP/1.0 connect send request send response Client ServerFriday, March 11, 2011
  77. 77. HTTP/1.0 connect send request send response close connection Client ServerFriday, March 11, 2011
  78. 78. HTTP/1.0 connect send request send response close connection Client connect ServerFriday, March 11, 2011
  79. 79. HTTP/1.0 connect send request send response close connection Client connect Server send requestFriday, March 11, 2011
  80. 80. HTTP/1.0 connect send request send response close connection Client connect Server send request send response dataFriday, March 11, 2011
  81. 81. HTTP/1.0 connect send request send response close connection Client connect Server send request send response data ...Friday, March 11, 2011
  82. 82. HTTP/1.0 connect send request send response close connection Client connect Server send request send response data ... send response dataFriday, March 11, 2011
  83. 83. HTTP/1.0 connect send request send response close connection Client connect Server send request send response data ... send response data close connectionFriday, March 11, 2011
  84. 84. HTTP/1.1: Content-length Client ServerFriday, March 11, 2011
  85. 85. HTTP/1.1: Content-length connect Client ServerFriday, March 11, 2011
  86. 86. HTTP/1.1: Content-length connect Connection: keep-alive Client ServerFriday, March 11, 2011
  87. 87. HTTP/1.1: Content-length connect Connection: keep-alive send request Client ServerFriday, March 11, 2011
  88. 88. HTTP/1.1: Content-length connect Connection: keep-alive send request send response Client ServerFriday, March 11, 2011
  89. 89. HTTP/1.1: Content-length connect Connection: keep-alive send request send response Content-length: xxx Client ServerFriday, March 11, 2011
  90. 90. HTTP/1.1: Content-length connect Connection: keep-alive send request send response Content-length: xxx Client ... ServerFriday, March 11, 2011
  91. 91. HTTP/1.1: Content-length connect Connection: keep-alive send request send response Content-length: xxx Client ... Server send requestFriday, March 11, 2011
  92. 92. HTTP/1.1: Content-length connect Connection: keep-alive send request send response Content-length: xxx Client ... Server send request send responseFriday, March 11, 2011
  93. 93. HTTP/1.1: Content-length connect Connection: keep-alive send request send response Content-length: xxx Client ... Server send request send response Content-length: yyyFriday, March 11, 2011
  94. 94. HTTP/1.1: Content-length connect Connection: keep-alive send request send response Content-length: xxx Client ... Server send request send response Content-length: yyy close connectionFriday, March 11, 2011
  95. 95. HTTP/1.1: Transfer-encoding: chunked Client ServerFriday, March 11, 2011
  96. 96. HTTP/1.1: Transfer-encoding: chunked connect Connection: keep-alive Client ServerFriday, March 11, 2011
  97. 97. HTTP/1.1: Transfer-encoding: chunked connect Connection: keep-alive send request Client ServerFriday, March 11, 2011
  98. 98. HTTP/1.1: Transfer-encoding: chunked connect Connection: keep-alive send request send response data Client ServerFriday, March 11, 2011
  99. 99. HTTP/1.1: Transfer-encoding: chunked connect Connection: keep-alive send request send response data Transfer-encoding: chunked Client ServerFriday, March 11, 2011
  100. 100. HTTP/1.1: Transfer-encoding: chunked connect Connection: keep-alive send request send response data Transfer-encoding: chunked Client xxx↵[data] ServerFriday, March 11, 2011
  101. 101. HTTP/1.1: Transfer-encoding: chunked connect Connection: keep-alive send request send response data Transfer-encoding: chunked Client xxx↵[data] Server send response data xxx↵[data]Friday, March 11, 2011
  102. 102. HTTP/1.1: Transfer-encoding: chunked connect Connection: keep-alive send request send response data Transfer-encoding: chunked Client xxx↵[data] Server send response data xxx↵[data] send response data 0↵Friday, March 11, 2011
  103. 103. HTTP/1.1: Transfer-encoding: chunked connect Connection: keep-alive send request send response data Transfer-encoding: chunked Client xxx↵[data] Server send response data xxx↵[data] send response data 0↵ close connectionFriday, March 11, 2011
  104. 104. http.createServer(function(request, response) { var uri = url.parse(request.url).pathname; var filename = path.join(process.cwd(), dir, uri); path.exists(filename, function(exists) { if(exists) { f = fs.createReadStream(filename); f.on(open, function() { response.writeHead(200); }); f.on(data, function(chunk) { response.write(chunk); }); f.on(error, function(err) { // ... }); f.on(end, function() { response.end(); }); } else { response.writeHead(404); - response.end(); } }); }).listen(port); stream- le-server.jsFriday, March 11, 2011
  105. 105. var hashFile = function(filename, cb) { path.exists(filename, function(exists) { if(exists) { r = fs.createReadStream(filename); var hash = crypto.createHash(md5); r.on(data, function(data) { hash.update(data); }); r.on(end, function() { cb(hash.digest(base64)); }); } else { throw File + filename + does not exist or can not be read; } }); } var filename = path.join(process.argv[2]); hashFile(filename, function(hash) { console.log(filename + : + hash); }); hash- le-stream.js (see stream- le-server-md5.js)Friday, March 11, 2011
  106. 106. var options = function(request) { // ... } http.createServer(function(request, response) { sys.log("--> " + request.url); var remoteRequest = http.request(options(request), function (remoteResponse) { response.writeHead(remoteResponse.statusCode, remoteResponse.headers); remoteResponse.on(data, function (chunk) { response.write(chunk); }); remoteResponse.on(end, function () { sys.log("<-- " + response.statusCode + " " + request.url); response.end(); }); }); request.on(data, function (chunk) { remoteRequest.write(chunk); }); request.on(end, function () { remoteRequest.end(); }); }).listen(port); proxy.jsFriday, March 11, 2011
  107. 107. http.createServer(function(request, response) { sys.log("--> " + request.url); var remoteRequest = http.request(options(request), function (remoteResponse) { response.writeHead(remoteResponse.statusCode, remoteResponse.headers); remoteResponse.on(end, function () { sys.log("<-- " + response.statusCode + " " + request.url); }); util.pump(remoteResponse, response); }); util.pump(request, remoteRequest); }).listen(port); proxy-pump.jsFriday, March 11, 2011
  108. 108. Asynchronous Programming ChallengesFriday, March 11, 2011
  109. 109. or: Why Programming with Callbacks SucksFriday, March 11, 2011
  110. 110. Friday, March 11, 2011
  111. 111. var bold = function(text) { return text.bold(); }; var capitalize = function(text) { return text.toUpperCase(); }; console.log("Synchronous:"); var result1 = capitalize("Hello, synchronous world."); var result2 = bold(result1); console.log("Sync result is " + result2); async1.jsFriday, March 11, 2011
  112. 112. var boldAsync = function(text, callback) { setTimeout(function (text) { callback(text.bold()); }, 100, text); }; var capitalizeAsync = function(text, callback) { setTimeout(function (text) { callback(text.toUpperCase()); }, 100, text); }; async1.jsFriday, March 11, 2011
  113. 113. var boldAsync = function(text, callback) { setTimeout(function (text) { callback(text.bold()); }, 100, text); }; var capitalizeAsync = function(text, callback) { setTimeout(function (text) { callback(text.toUpperCase()); }, 100, text); }; console.log("Asynchronous:"); capitalizeAsync("Hello, asynchronous world.", function(result1) { boldAsync(result1, function(result2) { console.log("Async result is " + result2); }); }); async1.jsFriday, March 11, 2011
  114. 114. try { console.log("Synchronous:"); var result1 = capitalize(null); var result2 = bold(result1); console.log("Sync result is " + result2); } catch (exception) { console.log("Sync exception caught: " + exception); } async2.jsFriday, March 11, 2011
  115. 115. try { console.log("Asynchronous:"); capitalizeAsync(text, function(result1) { boldAsync(result1, function(result2) { console.log("Async result is " + result2); }); }); } catch (exception) { console.log("Async exception caught: " + exception); } async2.jsFriday, March 11, 2011
  116. 116. // bad, dont do this try { console.log("Asynchronous:"); capitalizeAsync(text, function(result1) { boldAsync(result1, function(result2) { console.log("Async result is " + result2); }); }); } catch (exception) { console.log("Async exception caught: " + exception); } async2.jsFriday, March 11, 2011
  117. 117. var boldAsync = function(text, callback) { setTimeout(function (text) { try { callback(null, text.bold()); } catch (exception) { callback(exception); } }, 100, text); }; var capitalizeAsync = function(text, callback) { setTimeout(function (text) { try { callback(null, text.toUpperCase()); } catch (exception) { callback(exception); } }, 100, text); }; async3.jsFriday, March 11, 2011
  118. 118. capitalizeAsync(text, function(err, result1) { if (!err) { boldAsync(result1, function(err, result2) { if (!err) { console.log("Async result is " + result2); } else { console.log("Handling async error: " + err); } }); } else { console.log("Handling async error: " + err); } }); async3.jsFriday, March 11, 2011
  119. 119. var handleError = function(err, fn) { if (err) { console.log("Handling async error: " + err); } else { fn(); } } capitalizeAsync(text, function(err, result1) { handleError(err, function () { boldAsync(result1, function(err, result2) { handleError(err, function () { console.log("Async result is " + result2); }); }); }); }); async3.jsFriday, March 11, 2011
  120. 120. var step = require("step"); step( function () { capitalizeAsync(text, this); }, function (err, result) { if (err) throw err; boldAsync(result, this); }, function(err, result) { if (err) { console.log("Handling async error: " + err); } else { console.log("Async result is " + result); } } ); async3.jsFriday, March 11, 2011
  121. 121. var words = [one, two, three, four, five]; var upcasedWords = []; words.forEach(function (word) { capitalize(word, function(err, word) { upcasedWords.push(word); }); }); console.log(Done, upcased words: < + upcasedWords.join( ) + >); parallel1.jsFriday, March 11, 2011
  122. 122. var words = [one, two, three, four, five]; var upcasedWords = []; // bad, dont do this words.forEach(function (word) { capitalize(word, function(err, word) { upcasedWords.push(word); }); }); console.log(Done, upcased words: < + upcasedWords.join( ) + >); parallel1.jsFriday, March 11, 2011
  123. 123. var count = words.length; words.forEach(function (word) { capitalize(word, function(err, word) { upcasedWords.push(word); if (--count === 0) { console.log(Done, upcased words: < + upcasedWords.join( ) + >); } }); }); parallel1.jsFriday, March 11, 2011
  124. 124. var words = [one, two, three, four, five]; step( function () { var i, length; for (i = 0, length = words.length; i < length; i++) { capitalize(words[i], this.parallel()); } }, function (err) { if (err) throw err; var upcasedWords = Array.prototype.slice.call(arguments); upcasedWords.shift(); console.log(Done, upcased words: < + upcasedWords.join( ) + >); } ); parallel2.jsFriday, March 11, 2011
  125. 125. Tools & EcosystemFriday, March 11, 2011
  126. 126. Friday, March 11, 2011
  127. 127. npm node package manager Connect Asynchronous, low-level HTTP handler framework inspired by Rack/WSGI Express Sinatra-inspired Web framework on top of Connect multi-node Spawns child processes sharing listeners node-inspector Visual debugger for Node.js >700 more modules see https://github.com/joyent/node/ wiki/modulesFriday, March 11, 2011
  128. 128. var multi = require("multi-node"); var server = http.createServer(function(request, response) { var uri = url.parse(request.url).pathname; var filename = path.join(process.cwd(), dir, uri); path.exists(filename, function(exists) { if(exists) { fs.readFile(filename, function(err, data) { if (err) { sys.log(Error serving file + filename + + err); sys.log(request: + uri); } response.writeHead(200, { X-Node-Id: process.pid }); response.end(data); }); } else { response.writeHead(404); response.end(); } }); }); var nodes = multi.listen({ port: port, nodes: 10 }, server); sys.log("Server " + process.pid + " running at http://localhost:" + port); multi- le-server.jsFriday, March 11, 2011
  129. 129. SummaryFriday, March 11, 2011
  130. 130. Node.js popularizes the “right way” of network programmingFriday, March 11, 2011
  131. 131. JavaScript doesn’t suck as much as you thinkFriday, March 11, 2011
  132. 132. There’s a smart and active communityFriday, March 11, 2011
  133. 133. Node.js is fun to use!Friday, March 11, 2011
  134. 134. Thank you! Q&AFriday, March 11, 2011
  1. A particular slide catching your eye?

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

×