Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Node.js API pitfalls

128 views

Published on

Sam Roberts presents Node.js API pitfalls at the Summer 2016 Toronto Node.js meetup.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Node.js API pitfalls

  1. 1. Disclaimer ;-) Doesn't necessarily reflect the views of IBM, or any of my Node.js collaborators... 1
  2. 2. nextTick •  [ ] in next tick of the event loop •  [ ] immediately after A returns 2 process.nextTick(function() { // Called ... });
  3. 3. nextTick •  [ ] in next tick of the event loop •  [x] immediately after A returns 3 process.nextTick(function() { // Called ... });
  4. 4. setImmediate •  [ ] in next tick of the event loop •  [ ] immediately after A returns 4 setImmediate(function() { // Called ... });
  5. 5. setImmediate •  [x] in next tick of the event loop •  [ ] immediately after A returns 5 setImmediate(function() { // Called ... });
  6. 6. nextTick vs setImmediate •  nextTick: adds callback to queue to be called immediately •  setImmediate: adds callback to queue to be called next tick 6
  7. 7. worker.kill() 7 var cluster = require('cluster'); if (cluster.isMaster) { cluster.fork() .on('online', function() { this.kill('SIGHUP'); }) .on('exit', function() { console.log('Exit'); }); } else { process.on('SIGHUP', function() { console.log('Hup'); }); }
  8. 8. worker.kill() •  [ ] "Hup" •  [ ] "Exit" •  [ ] "Hup" and "Exit" •  [ ] No output 8 var cluster = require('cluster'); if (cluster.isMaster) { cluster.fork() .on('online', function() { this.kill('SIGHUP'); }) .on('exit', function() { console.log('Exit'); }); } else { process.on('SIGHUP', function() { console.log('Hup'); }); }
  9. 9. worker.kill() •  [ ] "Hup" •  [x] "Exit" •  [ ] "Hup" and "Exit" •  [ ] No output 9 var cluster = require('cluster'); if (cluster.isMaster) { cluster.fork() .on('online', function() { this.kill('SIGHUP'); }) .on('exit', function() { console.log('Exit'); }); } else { process.on('SIGHUP', function() { console.log('Hup'); }); }
  10. 10. worker.kill() - what is it really? •  Use worker.process.kill() if you want to signal the worker •  Asymetric with worker.send(), worker.on('message', ...), etc. 10 Worker.prototype.kill = function(signo) { var proc = this.process; this.once('disconnect', function() { this.process.kill(signo || 'SIGTERM'); }); this.disconnect(); };
  11. 11. worker.suicide - kill the worker •  [ ] true •  [ ] false 11 var cluster = require('cluster'); if (cluster.isMaster) { cluster.fork() .on('online', function() { this.kill('SIGTERM'); }) .on('exit', function() { // this.suicide is .... }); } else { }
  12. 12. worker.suicide - kill the worker •  [x] true •  [ ] false 12 var cluster = require('cluster'); if (cluster.isMaster) { cluster.fork() .on('online', function() { this.kill('SIGTERM'); }) .on('exit', function() { // this.suicide is .... }); } else { }
  13. 13. worker.suicide - exit the worker •  [ ] true •  [ ] false 13 var cluster = require('cluster'); if (cluster.isMaster) { cluster.fork() .on('exit', function() { // this.suicide is .... }); } else { process.exit(0); }
  14. 14. worker.suicide - exit the worker •  [ ] true •  [x] false 14 var cluster = require('cluster'); if (cluster.isMaster) { cluster.fork() .on('exit', function() { // this.suicide is .... }); } else { process.exit(0); }
  15. 15. worker.suicide - what does it mean? •  worker.disconnect() in parent (implicitly done by worker.kill()) •  process.disconnect() in worker 15 Actual meaning: "orderly exit"
  16. 16. url.parse/format 16 var url = require('url'); var uri = url.parse('http://example.com:8080/path'); uri.host = 'ibm.com'; console.log(url.format(uri)); •  [ ] yes •  [ ] no Prints http://ibm.com:8080/path ...
  17. 17. url.parse/format 17 var url = require('url'); var uri = url.parse('http://example.com:8080/path'); uri.host = 'ibm.com'; console.log(url.format(uri)); •  [ ] yes •  [x] no: http://ibm.com/path Prints http://ibm.com:8080/path ...
  18. 18. url.parse/format •  host is "example.com:8080" •  hostname is "example.com" 18
  19. 19. url.parse/format 19 var url = require('url'); var uri = url.parse('http://example.com:8080/path'); uri.hostname = 'ibm.com'; console.log(url.format(uri)); •  [ ] yes •  [ ] no Prints http://ibm.com:8080/path ...
  20. 20. url.parse/format 20 var url = require('url'); var uri = url.parse('http://example.com:8080/path'); uri.hostname = 'ibm.com'; console.log(url.format(uri)); •  [ ] yes •  [x] no: http://example.com:8080/path Prints http://ibm.com:8080/path ...
  21. 21. url.parse/format •  hostname and port are ignored if host is present... 21
  22. 22. url.parse/format 22 var url = require('url'); var uri = url.parse('http://example.com:8080/path'); delete uri.host; uri.hostname = 'ibm.com'; console.log(url.format(uri)); •  http://ibm.com:8080/path, finally!
  23. 23. url.parse/format •  parse: "http://example:8080": – port is 8080 – host is "example:8080"... why not hostport? – hostname is "example"... why not host? •  format: hostname and port are ignored if hostname is present – shouldn't they be prefered if present? 23
  24. 24. path.parse/format 24 var path = require('path'); var bits = path.parse('some/dir/index.txt'); // has: .name, .ext bits.ext = '.html'; console.log(path.format(bits)); Logs some/dir/index.html... •  [ ] yes •  [ ] no
  25. 25. path.parse/format 25 var path = require('path'); var bits = path.parse('some/dir/index.txt'); bits.ext = '.html'; console.log(path.format(bits)); Logs some/dir/index.html... •  [ ] yes •  [x] no: some/dir/index.txt
  26. 26. path.parse/format 26 var path = require('path'); var bits = path.parse('some/dir/index.txt'); console.log(bits.base); // > index.txt delete bits.base bits.ext = '.html'; console.log(path.format(bits)); Logs some/dir/index.html... •  [ ] yes •  [ ] no Its probably like url...
  27. 27. path.parse/format 27 var path = require('path'); var bits = path.parse('some/dir/index.txt'); console.log(bits.base); // > index.txt delete bits.base bits.ext = '.html'; console.log(path.format(bits)); Logs some/dir/index.html... •  [ ] yes •  [x] no: some/dir/
  28. 28. path.parse/format 28 var path = require('path'); var bits = path.parse('some/dir/index.txt'); bits.base = bits.name + '.html'; console.log(path.format(bits)); // > some/dir/index.html Its just completely different, format always ignores name and ext. Correct:
  29. 29. streams v1, 2, 3 29 Note that, for backwards compatibility reasons, removing 'data' event handlers will not automatically pause the stream. Also, if there are piped destinations, then calling pause() will not guarantee that the stream will remain paused once those destinations drain and ask for more data. From https://nodejs.org/api/stream.html#stream_class_stream_readable:
  30. 30. streams v1, 2, 3 30 Note that, for backwards compatibility reasons, removing 'data' event handlers will not automatically pause the stream. Also, if there are piped destinations, then calling pause() will not guarantee that the stream will remain paused once those destinations drain and ask for more data. From https://nodejs.org/api/stream.html#stream_class_stream_readable: When can we delete backwards compat to v0.8?
  31. 31. Question •  Laurie Voss (@seldo), NPM, Nov. 28, 2015 31 What kind of node do you want: a good one? or a (mostly) v0.8 compatible one? @octetcloud As of right now, 30.4% of registered npm accounts are less than 6 months old.
  32. 32. Answer •  github, twitter, etc.. •  Be tolerant (or intolerant) of breakages, but what you say will effect what happens. 32 Its yours (and a lot of other people's) Node.js, speak out:
  33. 33. Flames to: •  github: @sam-github •  email: rsam@ca.ibm.com •  twitter: @octetcloud •  talk source: https://gist.github.com/sam-github/4c5c019b92cf95fb6571, or https://goo.gl/2RWpqE 33

×