Node.js  - Best practices
Upcoming SlideShare
Loading in...5
×
 

Like this? Share it with your network

Share

Node.js - Best practices

on

  • 48,387 views

Second talk given at the munich node.js user group meeting on Dec 1, 2011.

Second talk given at the munich node.js user group meeting on Dec 1, 2011.

Statistics

Views

Total Views
48,387
Views on SlideShare
44,056
Embed Views
4,331

Actions

Likes
185
Downloads
936
Comments
2

35 Embeds 4,331

http://www.scoop.it 3708
http://paper.li 179
http://team07.tistory.com 131
http://nanha.com 83
http://blog.sambervalley.com 55
http://localhost 25
https://twitter.com 25
http://us-w1.rockmelt.com 20
http://www.nanha.com 17
http://www.techgig.com 12
https://sendtoinc.com 10
http://staging.slideshare.com 10
http://beta.jolicloud.co 10
http://127.0.0.1 6
http://lab.peerjoin.net 4
http://sbs-consulting.ru 3
https://www.linkedin.com 3
http://faavorite.com 3
http://s.deeeki.com 3
http://jolidev-jolicloud.dotcloud.com 2
http://jolidev10-jolicloud.dotcloud.com 2
http://www.twylah.com 2
http://www.google.com 2
http://zootool.com 2
http://webcache.googleusercontent.com 2
http://minifrogsgameserver.com 2
http://www.linkedin.com 2
http://www.google.co.jp 1
http://www.mefeedia.com 1
http://apps.staging.webdoc.com 1
http://migueldev.com 1
http://nodeslide.herokuapp.com 1
http://bitly.com 1
http://the-refreshing-sip.blogspot.com 1
http://sambervalley.tumblr.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • \n
  • \n
  • If you’re function works like this, I will not use it\n
  • Otherwise JSON.parse(undefined) -> SyntaxError: Unexpected token ILLEGAL \n
  • Otherwise invalid JSON -> SyntaxError: Unexpected token ILLEGAL\n
  • Otherwise I always have to -> if (json instanceof Error) ...\n
  • Subtle: Do not catch errors inside your callback -> very unexpected results\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Fake photograph btw.: http://www.snopes.com/photos/politics/bushbook.asp\n
  • Nested callbacks are an actual concern in the node community\n
  • \n
  • \n
  • \n
  • \n
  • Please DO NOT EVER use exceptions for control flow.\n\nLike so many things in JS, JSON.parse() throwing exceptions is bullshit.\n
  • \n
  • \n
  • \n
  • Also known as Stage 3 / Bargaining stage in Kübler-Ross model of “The Five Stages of Grief”\n
  • \n
  • If rows.length === 0 the exception triggered from accessing rows[0].id will STALL your database driver. Not good!\n
  • \n
  • Higher level could be upstart / monit / etc.\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Node.js - Best practices Presentation Transcript

  • 1. Best PracticesFelix Geisendörfer Munich Node.js User Group 01.12.2011 (v1)
  • 2. (@)felixge(.de)Twitter / GitHub / IRC Felix Geisendörfer (Berlin, Germany)
  • 3. Callbacks
  • 4. A terrible Example:var fs = require(fs);function readJSON(path, cb) { fs.readFile(path, utf8, function(err, data) { cb(JSON.parse(data)); });}
  • 5. Error Delegationvar fs = require(fs);function readJSON(path, cb) { fs.readFile(path, utf8, function(err, data) { if (err) return cb(err); cb(JSON.parse(data)); });}
  • 6. Exception Handlingvar fs = require(fs);function readJSON(path, cb) { fs.readFile(path, utf8, function(err, data) { if (err) return cb(err); try { cb(JSON.parse(data)); } catch (err) { cb(err); } });}
  • 7. Error parameter firstvar fs = require(fs);function readJSON(path, cb) { fs.readFile(path, utf8, function(err, data) { if (err) return cb(err); try { cb(null, JSON.parse(data)); } catch (err) { cb(err); } });}
  • 8. Not your errorvar fs = require(fs);function readJSON(path, cb) { fs.readFile(path, utf8, function(err, data) { if (err) return cb(err); try { var json = JSON.parse(data); } catch (err) { return cb(err); } cb(null, json); });}
  • 9. Another common mistakefunction readJSONFiles(files, cb) { var results = {}; var remaining = files.length; files.forEach(function(file) { readJSON(file, function(err, json) { if (err) return cb(err); results[file] = json; if (!--remaining) cb(null, results); }); });}
  • 10. Only call back oncefunction readJSONFiles(files, cb) { var results = {}; var remaining = files.length; files.forEach(function(file) { readJSON(file, function(err, json) { if (err) { cb(err); cb = function() {}; return; } results[file] = json; if (!--remaining) cb(null, results); }); });}
  • 11. Nested Callbacks
  • 12. db.query(SELECT A ..., function() { db.query(SELECT B ..., function() { db.query(SELECT C ..., function() { db.query(SELECT D ..., function() { db.query(SELECT E ..., function() { db.query(SELECT F ..., function() { db.query(SELECT G ..., function() { db.query(SELECT H ..., function() { db.query(SELECT I ..., function() { }); }); }); }); }); }); }); });});
  • 13. iPhone 4 owners?
  • 14. You are holding it wrong!
  • 15. Just kidding
  • 16. Control Flow Libs var async = require(async); async.series({ queryA: function(next) { db.query(SELECT A ..., next); }, queryB: function(next) { db.query(SELECT A ..., next); }, queryC: function(next) { db.query(SELECT A ..., next); } // ... }, function(err, results) { });
  • 17. Split code into more methods
  • 18. Maybe node.js is not a good tool for your problem?
  • 19. Exceptions(Dealing with Death)
  • 20. Exceptionsthrow new Error(oh no); Explicit, useful to crash your program
  • 21. Exceptionsnode.js:134 throw e; // process.nextTick error, or error event on first tick ^Error: oh no at Object.<anonymous> (/Users/felix/explicit.js:1:69) at Module._compile (module.js:411:26) at Object..js (module.js:417:10) at Module.load (module.js:343:31) at Function._load (module.js:302:12) at Array.<anonymous> (module.js:430:10) at EventEmitter._tickCallback (node.js:126:26) Output on stderr
  • 22. Exceptionsfunction MyClass() {}MyClass.prototype.myMethod = function() { setTimeout(function() { this.myOtherMethod(); }, 10);};MyClass.prototype.myOtherMethod = function() {};(new MyClass).myMethod(); Implicit, usually undesirable / bugs
  • 23. Exceptions/Users/felix/implicit.js:5 this.myOtherMethod(); ^TypeError: Object #<Object> has no method myOtherMethod at Object._onTimeout (/Users/felix/implicit.js:5:10) at Timer.callback (timers.js:83:39) Incomplete stack trace : (
  • 24. Global Catchprocess.on(uncaughtException, function(err) { console.error(uncaught exception: + err.stack);});
  • 25. Please be careful with this!
  • 26. Global catch gone wrong// Deep inside the database driver you are usingcb(null, rows);this._executeNextQueuedQuery();// In your codedb.query(SELECT ..., function(err, rows) { console.log(First row: + row[0].id);});
  • 27. If you have to:process.on(uncaughtException, function(err) { // You could use node-airbake for this sendErrorToLog(function() { // Once the error was logged, kill the process console.error(err.stack); process.exit(1); });});
  • 28. Even Better Processes die. Accept it.Deal with it on a higher level.
  • 29. Deployment
  • 30. Novice$ node server.js
  • 31. Advanced Beginner $ node server.js &
  • 32. Competent$ screen$ node server.js
  • 33. Proficient#!/bin/bashwhile :do node server.js echo "Server crashed!" sleep 1done
  • 34. Expert#!upstartdescription "myapp"author "felix"start on (local-filesystems and net-device-upIFACE=eth0)stop on shutdownrespawn # restart when job diesrespawn limit 5 60 # give up restart after 5respawns in 60 secondsscript exec sudo -u www-data /path/to/server.js >> /var/log/myapp.log 2>&1end script
  • 35. Innovation$ git push joyent master$ git push nodejitsu master$ git push heroku master
  • 36. Questions? @felixge
  • 37. Thank you!