intro to node.js from the perspective of a perl hacker

29
Node.js Coding for the server in Javascript (from the perspective of a Perl hacker)

Upload: matt-sergeant

Post on 18-Dec-2014

7.916 views

Category:

Technology


0 download

DESCRIPTION

A brief talk about Node.js given to Kitchener/Waterloo Perl Mongers, September 2011.

TRANSCRIPT

Page 1: Intro to Node.js From the perspective of a Perl Hacker

Node.jsCoding for the server in Javascript

(from the perspective of a Perl hacker)

Page 2: Intro to Node.js From the perspective of a Perl Hacker

Why use Node?

Page 3: Intro to Node.js From the perspective of a Perl Hacker

1: Performance

Page 4: Intro to Node.js From the perspective of a Perl Hacker

Node.js vs Perl

Page 5: Intro to Node.js From the perspective of a Perl Hacker

Qpsmtpd vs Haraka

matt@Valour ~/Perl/node$ time /usr/libexec/postfix/smtp-source -l 5000 -m 50000 -s 100 -d -f matt@local -t [email protected] -c localhost:252550000

real 1m28.451suser 0m1.789ssys 0m6.357smatt@Valour ~/Perl/node$ time /usr/libexec/postfix/smtp-source -l 5000 -m 50000 -s 100 -d -f matt@local -t [email protected] -c localhost:252550000

real 0m12.020suser 0m1.730ssys 0m6.351s

Page 6: Intro to Node.js From the perspective of a Perl Hacker

2: Non-Blocking IO

Page 7: Intro to Node.js From the perspective of a Perl Hacker

What’s your CPU doing?

Core: ~1 instruction per cycle

L1 cache: 3 cycles

L2 cache: 14 cycles

RAM: ~250 cycles

Disk seek: 40 million cycles

Network: 240 million cycles

Source: http://duartes.org/gustavo/blog/post/what-your-computer-does-while-you-wait

Page 8: Intro to Node.js From the perspective of a Perl Hacker

Of course Perl has AIO

POE

AnyEvent

EV

Danga::Socket

The problem: CPAN modules aren’t AsyncTypical example: ORMs

Page 9: Intro to Node.js From the perspective of a Perl Hacker

3: The Language…

Page 10: Intro to Node.js From the perspective of a Perl Hacker

OK so it’s Javascript

It’s really not that bad, if you structure it well

Node.js has clean modules with no global namespace

I’m not missing all the $@%*& bullshit

exports.hook_rcpt = function (next, connection) { connection.relaying = true; next(OK);}

Page 11: Intro to Node.js From the perspective of a Perl Hacker

Classes are Functions

function Connection(client, server) { this.client = client; this.server = server; …}

var conn = new Connection(client, server);

Page 12: Intro to Node.js From the perspective of a Perl Hacker

Inheritance is weird, but works

var net = require('net');var util = require('util');

function Socket(options) { if (!(this instanceof Socket)) return new Socket(options); net.Socket.call(this, options); // like SUPER this.current_data = ''; this.on('data', this.process_data); this.on('end', this.process_end);}

util.inherits(Socket, net.Socket);

Page 13: Intro to Node.js From the perspective of a Perl Hacker

It’s just as messy as Perl

Stomp on inherited class “hash” entries

Parameter passing isn’t checked in any way

Has stuff you shouldn’t use and consider deprecated

Page 14: Intro to Node.js From the perspective of a Perl Hacker

It’s nicer than Perl…

No global variables (perlvar) nonsense

Regexps return an array of matches (0 = whole match, 1 = capture 1, 2 = capture 2, etc)

Most methods don’t mutate, which feels surprisingly nice

Less freaky syntax hidden corners

Page 15: Intro to Node.js From the perspective of a Perl Hacker

But it also sucks HARD

No lexical scope. Just global (module level) and function level.

for (i=0; i<10; i++) {

var j=i;

setTimeout(function () { console.log(j) }, 1000);

}

prints ten “9”s.

Page 16: Intro to Node.js From the perspective of a Perl Hacker

for (i=0; i<10; i++) { setTimeout((function (j) { return function () { console.log(j) } })(i), 1000);}

Outer function captures j (as JShas function variable scope)

Returns inner function whichuses j as a closure variable

We execute the outer functionpassing in i (which becomes j)

Page 17: Intro to Node.js From the perspective of a Perl Hacker

But it also sucks HARD

The “this” variable doesn’t stick around:

MyObject.prototype.do_something_later = function () {

setTimeout(function () { this._do_something() }, 1000);}

MyObject.prototype.do_something_later = function () { var self = this;

setTimeout(function () { self._do_something() }, 1000);}

Page 18: Intro to Node.js From the perspective of a Perl Hacker

Async can make things hard

What I’ve typically done before: if ($user->requires_moderation()) { # makes a DB call

… # moderate user

}

What you have to do in Async style: user.requires_moderation(function (err, flag) {

if (err) { … }

if (flag) {

// moderate user

}

});

Page 19: Intro to Node.js From the perspective of a Perl Hacker

Npm vs CPAN

Node Package Manager

(Obviously) a lot less stuff than CPAN

But still a surprising amount: 3831 packages as of writing

By default everything installs locally – no more screwing up apps by updating some library

For binary tools this still works. Binaries are symlinks to the install directory

Uploading is also much easier. “npm publish”. Done.

Page 20: Intro to Node.js From the perspective of a Perl Hacker

Debugging

Basic debugger built in, pretty shit really

Node-inspector – plugs into WebKit’s Javascript debugger

Page 21: Intro to Node.js From the perspective of a Perl Hacker

Profiling

Frankly, totally busted

Node-inspector has something but I can’t make it work

V8’s profiler is based on periodic snapshots, not a full profile

Page 22: Intro to Node.js From the perspective of a Perl Hacker

Other nice parts

Methods can be (re)defined on the fly – makes per-object methods trivial

Try/catch and switch part of core language

Named methods/functions are just variablesfunction blah () { } === var blah = function () { }

blah // variable containing the function

blah() // call the function

object.blah() === object[“blah”]()

It’s much more pure OO than Perlnot very many global functions

string.length vs length($string)

Page 23: Intro to Node.js From the perspective of a Perl Hacker

Node.js API

Timers, current process, Events, binary buffers, Streams, Crypto, Filesystem, Networking (IPv6 compatible), HTTP Server and client, Child processes, OS info

What’s Missing?Cmdline arg parsing

pack/unpack, flock, seek

Decent date/time manipulation

QuotedPrintable

Encode equivalent (iconv on NPM, but that lacks lots)

Test harness

Page 24: Intro to Node.js From the perspective of a Perl Hacker

Example of filesystem access

Hard way:

fs.open(path, ‘r’, function (err, fd) { if (err) { ... } var buf = new Buffer(1024); fs.read(fd, buf, 0, 1024, null, function (err, bytesRead, buf) { ... });});

Easy way:

var rs = fs.createReadStream(path);rs.on(‘error’, function (err) { ... });rs.on(‘data’, function (buf) { ... });

Note: no line-by-line reading built in

Page 25: Intro to Node.js From the perspective of a Perl Hacker

IPC coming in node 0.6var cp = require('child_process');

// Note: not what we know as fork() in POSIX/Perlvar n = cp.fork(__dirname + '/sub.js');

n.on('message', function(m) { console.log('PARENT got message:', m);});

n.send({ hello: 'world' }); // uses JSON internally

// in sub.js:process.on('message', function(m) { console.log('CHILD got message:', m);});

process.send({ foo: 'bar' });

Page 26: Intro to Node.js From the perspective of a Perl Hacker

IPC with hook.io

Available via NPM

Does transparent message passing between multiple listeners

Kind of like gearman for node, but maybe more feature complete

Page 27: Intro to Node.js From the perspective of a Perl Hacker

Using multiple CPUs

By default there’s no threading/forking

Needs a module – “cluster” from npm

var net = require(‘net’);var server = net.createServer(function (client) { // handle client connection});

server.listen(2525);

var cluster = require(‘cluster’);var net = require(‘net’);var server = net.createServer(function (client) { // handle client connection});var c = cluster(server);c.listen(2525);

Page 28: Intro to Node.js From the perspective of a Perl Hacker

Links:

http://nodejs.org/http://npmjs.org/https://github.com/baudehlo/Haraka

Page 29: Intro to Node.js From the perspective of a Perl Hacker

Thank You