matthew eernisse, nodejs, .toster {webdev}
TRANSCRIPT
![Page 1: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/1.jpg)
Intro to NodeJSMatthew Eernisse
Toster Conference 2011-10-282001
![Page 2: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/2.jpg)
Who am I?
Matthew EernisseWork at Yammer@mde on Twitter
![Page 3: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/3.jpg)
JavaScript at YammerBrowsers (yammer.com Web UI)
Adobe AIR Desktop
V8 in Rails via TheRubyRacer
NodeJS
•
•
•
•
![Page 4: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/4.jpg)
NodeJS:“Evented I/O for V8 JavaScript”
http://nodejs.org/
![Page 5: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/5.jpg)
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n');
}).listen(1337, "127.0.0.1");
console.log( 'Server running at http://127.0.0.1:1337/');
Hello, NodeJS
![Page 6: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/6.jpg)
Server JS
![Page 7: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/7.jpg)
Netscape Enterprise Server (OG SSJS)
Microsoft IIS
Helma (now RingoJS)
Whitebeam
Zimki
Jaxer
Perservere
Nitro
Google App Engine
CouchDB
NodeJS
•
•
•
•
•
•
•
•
•
•
•
History of SSJS
![Page 8: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/8.jpg)
Why NodeJS now?Steve Yegge’s NBL post, 2007-02-10
Competition in JavaScriptinterpreters
Simple, POSIX API
Non-blocking from the ground up; soare the libraries
•
•
•
•
![Page 9: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/9.jpg)
What is NodeJS good for?Lightweight, networked apps
Proxies with embedded logic
Streaming data
System scripting
Evented realtime apps
•••••
![Page 10: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/10.jpg)
NodeJS is not good at complexdatabase-backed Web
applications.You can use Rails.
![Page 11: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/11.jpg)
Geddy Web framework:https://github.com/mde/geddy
![Page 12: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/12.jpg)
NodeJS at YammerDevelopment proxy
Jake for build and test(https://github.com/mde/jake)
Upload service for files and images (Geddy v0.2)
Browserless tests with FooUnit (https://github.com/foobarfighter/foounit)
Realtime, collaborative document-editing service
•
•
•
•
•
![Page 13: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/13.jpg)
Jake build toolhttps://github.com/mde/jake•
Similar to Make or Rake
Tasks, prerequisites
File tasks, directory tasks
Namespaces
PackageTasks
Async task execution
Just executable JavaScript
•
•
•
•
•
•
•
![Page 14: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/14.jpg)
desc('This is the default task.');task('default', function () { console.log('This is the default task.'); console.dir(arguments);});
namespace('foo', function () { desc('This the foo:bar task'); task('bar', function () { console.log('doing foo:bar task'); console.dir(arguments); });
desc('This the foo:baz task'); task('baz', ['default', 'foo:bar'], function () { console.log('doing foo:baz task'); console.dir(arguments); });
});
![Page 15: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/15.jpg)
desc('This is an asynchronous task.');task('async', function () { setTimeout(function () { console.log('Hooray!'); complete(); }, 1000);}, true);
desc('Calls the foo:bar task and its dependencies.');task('invokeFooBar', function () { // Calls foo:bar and its deps jake.Task['foo:bar'].invoke(); // Does nothing jake.Task['foo:bar'].invoke(); // Only re-runs foo:bar, but not its dependencies jake.Task['foo:bar'].reenable(); jake.Task['foo:bar'].invoke();});
![Page 16: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/16.jpg)
var fs = require('fs') , pkg = JSON.parse( fs.readFileSync('package.json').toString()) , version = pkg.version
var t = new jake.PackageTask('jake', 'v' + version, function () { var fileList = [ 'Makefile' , 'Jakefile' , 'README.md' , 'package.json' , 'lib/*' , 'bin/*' , 'tests/*' ]; this.packageFiles.include(fileList); this.needTarGz = true; this.needTarBz2 = true;});
![Page 17: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/17.jpg)
Remote upload serviceMinimal v1 in prod, Nov. 2010
Redis, CORS XHR-push or JSONP for upload-progressreporting
Onboard thumbnailing, remote services for video anddocument post-processing
Three-machine cluster, not under a heavy load
Large file sizes (e.g., 1.5GB)
•
•
•
•
•
![Page 18: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/18.jpg)
Realtime, collaborative doc-editing service
In beta Oct. 21, 2011 (last week)
NodeJS, Socket.io, PostgreSQL
No production metrics yet for perf/scalability
•
•
•
![Page 19: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/19.jpg)
Coding JS for Node
![Page 20: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/20.jpg)
Awesome:JavaScript is simple and
super-flexible
![Page 21: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/21.jpg)
Horrible:JavaScript is simple and
super-flexible
![Page 22: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/22.jpg)
Even shelling out is async?
“1, 3, 2, go!” development
Evented and callback-based control-flow
A familiar model?
Async patterns and libraries
•••••
Asynchronous code
![Page 23: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/23.jpg)
var asyncFun = function () { console.log('1'); setTimeout(function () { console.log('3'); }, 0); console.log('2'); console.log('go!');};
1, 3, 2, go!
![Page 24: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/24.jpg)
var fetchAndUpdate = function (params) { var items = db.fetch(someQuery); for (var i = 0, ii = items.length; i++) { item.update(params); } return true;};
Sync fetch-and-update
![Page 25: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/25.jpg)
var fetchAndUpdate = function (params, callback) { db.fetch(someQuery, function (items) { var count = 0; for (var i = 0, ii = items.length; i++) { item.update(params, function () { count++; if (count == ii) { callback(true); } }); } });};
Async fetch-and-update
![Page 26: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/26.jpg)
jQuery.ajax({ url: '/foo/bar.json', success: function () { alert('yay!'); }});
jQuery('#foo').bind('click', function (e) { // Do some stuff});
Is this familiar?
![Page 27: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/27.jpg)
Async patterns and libs
Queue
Promise/deferred
In-flight registry
•••
![Page 28: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/28.jpg)
var asyncQueueHandler = function (items, handler, callback) { var queue = items.slice() , handleNextItem = function () { var next = queue.pop(); if (next) { handler(next, function () { handleNextItem(); }); } else { callback(); } }; handleNextItem();};
Queue
![Page 29: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/29.jpg)
var p = new yammer.util.Promise();p.when('foo', 'bar', 'baz').then( function () { console.log('done!');});p.satisfy('foo');p.satisfy('bar');p.satisfy('baz');
p.then(function () { console.log('still done!');});
Promise
![Page 30: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/30.jpg)
NodeJS in production
![Page 31: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/31.jpg)
Third-party modules still may changerapidly
Maintain forks, push back patches whereappropriate
•
•
App dependencies
![Page 32: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/32.jpg)
Callbacks in global scope have no stack
Assume you’re fucked
Default condition is a preemptible error
In-flight registry with uncaughtExceptionhandler
••••
Debugging NodeJS
![Page 33: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/33.jpg)
FlightCheckhttps://github.com/mde/flight_check•
Add items to in-flight registry
Per-item timeout
Configurable polling-interval
Define a timeout-handler
•
•
•
•
![Page 34: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/34.jpg)
var FlightCheck = require('flight_check').FlightCheck;var handler = function (req, resp) { var checker = new FlightCheck(function (key) { resp.writeHead(500); resp.end('Oops, something bad happened.'); }); checker.add('foo', 10000); doFoo(req, function (result) { if (result.ok) { checker.clear('foo'); // Do some other stuff resp.writeHead(200); resp.end('Hooray!'); } });};
process.on('uncaughtException', function (err) { // Do some kind of logging});
In-flight registry
![Page 35: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/35.jpg)
Measure everything
Log everything
https://github.com/mikejihbe/metrics
•••
Visibility, metrics
![Page 36: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/36.jpg)
Communicative, consultative dev
Ask what is expected
Play nicely with others
•••
Ops
![Page 37: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/37.jpg)
The future?JS interpreters will keep improving
JS language will keep improving (see:JS.next)
NodeJS ecosystem will grow and mature
Try NodeJS, you’ll like it
••
••
![Page 38: Matthew Eernisse, NodeJs, .toster {webdev}](https://reader034.vdocuments.site/reader034/viewer/2022051211/554a0ee0b4c9055c598b495c/html5/thumbnails/38.jpg)
Matthew Eernissehttp://twitter.com/mde
Yammer Developer Centerhttp://developer.yammer.com/