node.js A quick tour by Felix Geisendörfer 1 Donnerstag, 4. März 2010
Jan 15, 2015
node.jsA quick tour
by Felix Geisendörfer1Donnerstag, 4. März 2010
Who is talking?
• node.js hacker
• Cofounder of Debuggable
• CakePHP core alumnus
2Donnerstag, 4. März 2010
Why Node?
3Donnerstag, 4. März 2010
Why?
Node's goal is to provide an easy way to build scalable network programs.
-- nodejs.org
4Donnerstag, 4. März 2010
How?
Keep slow operations from blocking other operations.
5Donnerstag, 4. März 2010
Traditional I/O
var data = file.read('file.txt');doSomethingWith(data);
Something is not right here
6Donnerstag, 4. März 2010
Traditional I/O
var data = file.read('file.txt');
// zzzZZzzz
doSomethingWith(data);
Don’t waste those cycles!
FAIL!
7Donnerstag, 4. März 2010
Async I/O
file.read('file.txt', function(data) { doSomethingWith(data);});
doSomethingElse();
WIN ✔
No need to wait for the disk, do something else meanwhile!
8Donnerstag, 4. März 2010
The Present
9Donnerstag, 4. März 2010
Quality components
• V8 (developed for google chrome)
• libev (event loop)
• libeio (non-block posix, thread pool)
10Donnerstag, 4. März 2010
CommonJS Modules
exports.world = function() { return 'Hello World';};
hello.js
main.js
var hello = require('./hello');var sys = require('sys');sys.puts(hello.world());
$ node main.jsHello World
11Donnerstag, 4. März 2010
Child processes
var child = process.createChildProcess('sh',['-c', 'echo hello; sleep 1; echo world;']);child.addListener('data', function (chunk) { p(chunk);});
$ node child.js "hello\n"# 1 sec delay"world\n"null
child.js
12Donnerstag, 4. März 2010
Http Server
var http = require('http');http.createServer(function(req, res) { setTimeout(function() { res.writeHeader(200, {'Content-Type': 'text/plain'}); res.write('Thanks for waiting!'); res.close(); }, 1000);}).listen(4000);
$ curl localhost:4000# 1 sec delayThanks for waiting!
13Donnerstag, 4. März 2010
Tcp Servervar tcp = require('tcp');tcp.createServer(function(socket) { socket.addListener('connect', function() { socket.write("Hi, How Are You?\n> "); }); socket.addListener('data', function(data) { socket.write(data); });}).listen(4000);
$ nc localhost 4000Hi, How Are You?> Great!Great!
14Donnerstag, 4. März 2010
DNS
var dns = require('dns');dns.resolve4('nodejs.org', function(err, addr, ttl, cname) { p(addr, ttl, cname);});
dns.js
$ node dns.js[ '97.107.132.72' ]84279'nodejs.org'
15Donnerstag, 4. März 2010
Watch File
process.watchFile(__filename, function() { puts('You changed me!'); process.exit();});
watch.js
$ node watch.js# edit watch.jsYou changed me!
16Donnerstag, 4. März 2010
ECMAScript 5
• Getters / settersvar a = {};a.__defineGetter__('foo', function() { return 'bar';});puts(a.foo);
• Array: filter, forEach, reduce, etc.
• JSON.stringify(), JSON.parse()& more [1]
17Donnerstag, 4. März 2010
There is only 1 thread
file.read('file.txt', function(data) { // Will never fire});
while (true) { // this blocks the entire process}
Good for conceptual simplicityBad for CPU-bound algorithms
18Donnerstag, 4. März 2010
The Future
19Donnerstag, 4. März 2010
Web workers
• Multiple node processes that do interprocess communication
• CPU-bound algorithms can run separately
• Multiple CPU cores can be used efficiently
20Donnerstag, 4. März 2010
Streams
see [2]
• Node is working towards a unified data stream interface
• Stream can be readable, writable or both
21Donnerstag, 4. März 2010
Readable Streams
• events: ‘data’, ‘end’
• methods: pause(), resume()
22Donnerstag, 4. März 2010
Writeable Streams
• events: ‘drain’, ‘close’
• methods: write(), close()
23Donnerstag, 4. März 2010
Stream Redirection
http.createServer(function (req, res) { // Open writable file system var temp = fs.openTemporaryFile(); // Pump the request into the temp file. stream.pump(req, temp, function (err) { if (err) throw err;
p('sweet!'); });});
24Donnerstag, 4. März 2010
Better Socket Support
• Support for unix sockets, socketpair(), pipe()
• Pass sockets between processes ➠ load balance requests between web workers
25Donnerstag, 4. März 2010
Debugger
• V8 support debugging
• Node has a few bugs with exposing the debugger, those need fixing
• Command line node-debug REPL tool
26Donnerstag, 4. März 2010
Readline and Curses
• Bindings for JavaScript
• Would allow to build better command line tools
• Goal should be to write a screen clone in node
27Donnerstag, 4. März 2010
HTML and XML parsing
• HTML is a major protocol
• Node should be able to parse dirty XML/HTML
• Should be a SAX-style parser in pure JS
28Donnerstag, 4. März 2010
Support for Windows
• Patches welcome! : )
29Donnerstag, 4. März 2010
Hot code reloading
• Reload module during runtime
• Update code without taking server offline
(maybe)
30Donnerstag, 4. März 2010
Suitable Applications
• Web frameworks
• Real time
• Crawlers
31Donnerstag, 4. März 2010
More Applications
• Process monitoring
• File uploading
• Streaming
32Donnerstag, 4. März 2010
Let’s write a chat
33Donnerstag, 4. März 2010
Http Chat in 14 LoCvar http = require('http'), messages = [];
http.createServer(function(req, res) { res.writeHeader(200, {'Content-Type' : 'text/plain'}); if (req.url == '/') { res.write(messages.join("\n")); } else if (req.url !== '/favicon.ico') { messages.push(decodeURIComponent(req.url.substr(1))); res.write('ok!'); } res.close();}).listen(4000);
34Donnerstag, 4. März 2010
Production ready?
• For small systems, yes.
• Perfect example: Comet server
• Usually few bugs, but API is still changing
35Donnerstag, 4. März 2010
Questions?
☝@felixge
http://debuggable.com/$✎
36Donnerstag, 4. März 2010
Links[1]: http://wiki.github.com/ry/node/ecma-5mozilla-features-implemented-in-v8[2]: http://wiki.github.com/ry/node/streams
37Donnerstag, 4. März 2010
Bonus Slides!
38Donnerstag, 4. März 2010
Dirty
Dirty
JavaScript ViewsDisk Persistence
Memory StoreSpeed > Safety
39Donnerstag, 4. März 2010
A scriptable key-value store
• Let your business logic and your data share the same memory / process
• Network = OVERHEAD - Avoid whenever possible
• V8 makes it very fast
40Donnerstag, 4. März 2010
How fast?
• Set: 3-5 million docs / sec
• Get: 40-50 million docs / sec
(on my laptop - your milage may vary)41Donnerstag, 4. März 2010
Benchmarks
Do your own!
42Donnerstag, 4. März 2010
Disk persistence
• Append-only log
• Writes happen every x-Sec or every x-Records
• Callbacks fire after disk write succeeded
43Donnerstag, 4. März 2010
Dirty Hello World
$ node hello.js$ cat test.dirty {"hello":"dirty world!","_key":"3b8f86..."}{"looks":"nice","_key":"my-key"}
var Dirty = require('dirty').Dirty, posts = new Dirty('test.dirty');
posts.add({hello: 'dirty world!'});posts.set('my-key', {looks: 'nice'});
hello.js
44Donnerstag, 4. März 2010
Reloading from Disk
var Dirty = require('dirty').Dirty, posts = new Dirty('test.dirty');
posts.load(function() { p(posts.get('my-key'));});
$ node hello.js{"looks": "nice", "_key": "my-key"}
hello.js
45Donnerstag, 4. März 2010
Use Cases
• Small projects (db < memory)
• Rapid prototyping
• Add HTTP/TCP interface and scale
46Donnerstag, 4. März 2010
http://github.com/felixge/node-dirty
(or google for “dirty felixge”)
47Donnerstag, 4. März 2010