Matthew Eernisse, NodeJs, .toster {webdev}

Preview:

Citation preview

Intro to NodeJSMatthew Eernisse

Toster Conference 2011-10-282001

Who am I?

Matthew EernisseWork at Yammer@mde on Twitter

JavaScript at YammerBrowsers (yammer.com Web UI)

Adobe AIR Desktop

V8 in Rails via TheRubyRacer

NodeJS

NodeJS:“Evented I/O for V8 JavaScript”

http://nodejs.org/

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

Server JS

Netscape Enterprise Server (OG SSJS)

Microsoft IIS

Helma (now RingoJS)

Whitebeam

Zimki

Jaxer

Perservere

Nitro

Google App Engine

CouchDB

NodeJS

History of SSJS

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

What is NodeJS good for?Lightweight, networked apps

Proxies with embedded logic

Streaming data

System scripting

Evented realtime apps

•••••

NodeJS is not good at complexdatabase-backed Web

applications.You can use Rails.

Geddy Web framework:https://github.com/mde/geddy

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

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

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); });

});

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();});

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;});

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)

Realtime, collaborative doc-editing service

In beta Oct. 21, 2011 (last week)

NodeJS, Socket.io, PostgreSQL

No production metrics yet for perf/scalability

Coding JS for Node

Awesome:JavaScript is simple and

super-flexible

Horrible:JavaScript is simple and

super-flexible

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

var asyncFun = function () { console.log('1'); setTimeout(function () { console.log('3'); }, 0); console.log('2'); console.log('go!');};

1, 3, 2, go!

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

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

jQuery.ajax({ url: '/foo/bar.json', success: function () { alert('yay!'); }});

jQuery('#foo').bind('click', function (e) { // Do some stuff});

Is this familiar?

Async patterns and libs

Queue

Promise/deferred

In-flight registry

•••

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

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

NodeJS in production

Third-party modules still may changerapidly

Maintain forks, push back patches whereappropriate

App dependencies

Callbacks in global scope have no stack

Assume you’re fucked

Default condition is a preemptible error

In-flight registry with uncaughtExceptionhandler

••••

Debugging NodeJS

FlightCheckhttps://github.com/mde/flight_check•

Add items to in-flight registry

Per-item timeout

Configurable polling-interval

Define a timeout-handler

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

Measure everything

Log everything

https://github.com/mikejihbe/metrics

•••

Visibility, metrics

Communicative, consultative dev

Ask what is expected

Play nicely with others

•••

Ops

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

••

••

Matthew Eernissehttp://twitter.com/mde

Yammer Developer Centerhttp://developer.yammer.com/

Recommended