Node.js<br />Coding for the server in Javascript<br />(from the perspective of a Perl hacker)<br />
Why use Node?<br />
1: Performance<br />
Node.jsvs Perl<br />
QpsmtpdvsHaraka<br />matt@Valour ~/Perl/node$ time /usr/libexec/postfix/smtp-source -l 5000 -m 50000 -s 100 -d -f matt@loc...
2: Non-Blocking IO<br />
What’s your CPU doing?<br />Core: ~1 instruction per cycle<br />L1 cache: 3 cycles<br />L2 cache: 14 cycles<br />RAM: ~250...
Of course Perl has AIO<br />POE<br />AnyEvent<br />EV<br />Danga::Socket<br />The problem: CPAN modules aren’t Async<br />...
3: The Language…<br />
OK so it’s Javascript<br />It’s really not that bad, if you structure it well<br />Node.js has clean modules with no globa...
Classes are Functions<br />function Connection(client, server) {<br />this.client = client;<br />this.server = server;<br ...
Inheritance is weird, but works<br />var net  = require('net');<br />varutil = require('util');<br />function Socket(optio...
It’s just as messy as Perl<br />Stomp on inherited class “hash” entries<br />Parameter passing isn’t checked in any way<br...
It’s nicer than Perl…<br />No global variables (perlvar) nonsense<br />Regexps return an array of matches (0 = whole match...
But it also sucks HARD<br />No lexical scope. Just global (module level) and function level.<br />for (i=0; i<10; i++) {<b...
for (i=0; i<10; i++) {<br />setTimeout((function (j) { <br />returnfunction () {<br />console.log(j)<br />       }<br />  ...
But it also sucks HARD<br />The “this” variable doesn’t stick around:<br />MyObject.prototype.do_something_later = functio...
Async can make things hard<br />What I’ve typically done before:<br />    if ($user->requires_moderation()) { # makes a DB...
Npmvs CPAN<br />Node Package Manager<br />(Obviously) a lot less stuff than CPAN<br />But still a surprising amount: 3831 ...
Debugging<br />Basic debugger built in, pretty shit really<br />Node-inspector – plugs into WebKit’sJavascript debugger<br />
Profiling<br />Frankly, totally busted<br />Node-inspector has something but I can’t make it work<br />V8’s profiler is ba...
Other nice parts<br />Methods can be (re)defined on the fly – makes per-object methods trivial<br />Try/catch and switch p...
Node.js API<br />Timers, current process, Events, binary buffers, Streams, Crypto, Filesystem, Networking (IPv6 compatible...
Example of filesystem access<br />Hard way:<br />fs.open(path, ‘r’, function (err, fd) {<br /> if (err) { ... }<br />varbu...
IPC coming in node 0.6<br />varcp = require('child_process');<br />// Note: not what we know as fork() in POSIX/Perl<br />...
IPC with hook.io<br />Available via NPM<br />Does transparent message passing between multiple listeners<br />Kind of like...
Using multiple CPUs<br />By default there’s no threading/forking<br />Needs a module – “cluster” from npm<br />var cluster...
Links:<br />http://nodejs.org/<br />http://npmjs.org/<br />https://github.com/baudehlo/Haraka<br />
Thank You<br />
Upcoming SlideShare
Loading in...5
×

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

9,001

Published on

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

Published in: Technology
2 Comments
5 Likes
Statistics
Notes
  • Considering how 'young' nodejs is, and that it's now on 0.8 (and this deck is addressing 0.5) I'm really impressed. I wrote a program last week in PERL and someone told me to try the same program in javascript using node and I'll tell you that the node version runs about 33% faster. I was really surprised. I've done a lot of javascript (client side) and for those dipping their toes in javascript, learn about closures. And when you almost have it, learn more about closures. They make sense after a while, but it's a very different type of scoping from C/PERL/Java etc...
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Didn't quite get the chart at Slide 4, but Slide 15 is fantastic at illustrating how counter-intuitive Node.js programming can be.

    Npmjs.org is crap compared to CPAN - https://github.com/isaacs/npm-www/issues/298

    And great comment on Slide 24 - no line-by-line reading built in. It's crazy how such a basic construct still is impossible or super cumbersome to do in Node.js - see http://stackoverflow.com/questions/6156501/read-a-file-one-line-at-a-time-in-node-js
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
9,001
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
23
Comments
2
Likes
5
Embeds 0
No embeds

No notes for slide
  • An admittedly synthetic test. Whereperl is faster it has used internal ops like tr/// that JS doesn’t have. What this proves is that plain OPS in JS are faster – significantly.
  • 40,000,000 / 250 = 160,000  Things your CPU could be doing to RAM in that time.
  • But eventually V8 is going to get “let” which makes this all moot.
  • Exceptions have to be caught the old fashioned way, because they happen from the event loop, not from this point in the code.
  • Intro to Node.js From the perspective of a Perl Hacker

    1. 1. Node.js<br />Coding for the server in Javascript<br />(from the perspective of a Perl hacker)<br />
    2. 2. Why use Node?<br />
    3. 3. 1: Performance<br />
    4. 4. Node.jsvs Perl<br />
    5. 5. QpsmtpdvsHaraka<br />matt@Valour ~/Perl/node$ time /usr/libexec/postfix/smtp-source -l 5000 -m 50000 -s 100 -d -f matt@local -t matt@haraka.local -c localhost:2525<br />50000<br />real 1m28.451s<br />user 0m1.789s<br />sys 0m6.357s<br />matt@Valour ~/Perl/node$ time /usr/libexec/postfix/smtp-source -l 5000 -m 50000 -s 100 -d -f matt@local -t matt@haraka.local -c localhost:2525<br />50000<br />real 0m12.020s<br />user 0m1.730s<br />sys 0m6.351s<br />
    6. 6. 2: Non-Blocking IO<br />
    7. 7. What’s your CPU doing?<br />Core: ~1 instruction per cycle<br />L1 cache: 3 cycles<br />L2 cache: 14 cycles<br />RAM: ~250 cycles<br />Disk seek: 40 million cycles<br />Network: 240 million cycles<br />Source: http://duartes.org/gustavo/blog/post/what-your-computer-does-while-you-wait<br />
    8. 8. Of course Perl has AIO<br />POE<br />AnyEvent<br />EV<br />Danga::Socket<br />The problem: CPAN modules aren’t Async<br />Typical example: ORMs<br />
    9. 9. 3: The Language…<br />
    10. 10. OK so it’s Javascript<br />It’s really not that bad, if you structure it well<br />Node.js has clean modules with no global namespace<br />I’m not missing all the $@%*& bullshit<br />exports.hook_rcpt = function (next, connection) {<br />connection.relaying = true;<br /> next(OK);<br />}<br />
    11. 11. Classes are Functions<br />function Connection(client, server) {<br />this.client = client;<br />this.server = server;<br /> …<br />}<br />var conn = new Connection(client, server);<br />
    12. 12. Inheritance is weird, but works<br />var net = require('net');<br />varutil = require('util');<br />function Socket(options) {<br /> if (!(this instanceof Socket)) return new Socket(options);<br />net.Socket.call(this, options); // like SUPER<br />this.current_data = '';<br />this.on('data', this.process_data);<br />this.on('end', this.process_end);<br />}<br />util.inherits(Socket, net.Socket);<br />
    13. 13. It’s just as messy as Perl<br />Stomp on inherited class “hash” entries<br />Parameter passing isn’t checked in any way<br />Has stuff you shouldn’t use and consider deprecated<br />
    14. 14. It’s nicer than Perl…<br />No global variables (perlvar) nonsense<br />Regexps return an array of matches (0 = whole match, 1 = capture 1, 2 = capture 2, etc)<br />Most methods don’t mutate, which feels surprisingly nice<br />Less freaky syntax hidden corners<br />
    15. 15. But it also sucks HARD<br />No lexical scope. Just global (module level) and function level.<br />for (i=0; i<10; i++) {<br />var j=i;<br />setTimeout(function () { console.log(j) }, 1000);<br />}<br />prints ten “9”s.<br />
    16. 16. for (i=0; i<10; i++) {<br />setTimeout((function (j) { <br />returnfunction () {<br />console.log(j)<br /> }<br /> })(i), 1000);<br />}<br />Outer function captures j (as JS<br />has function variable scope)<br />Returns inner function which<br />uses j as a closure variable<br />We execute the outer function<br />passing in i (which becomes j)<br />
    17. 17. But it also sucks HARD<br />The “this” variable doesn’t stick around:<br />MyObject.prototype.do_something_later = function () {<br />setTimeout(function () {<br />this._do_something()<br /> }, 1000);<br />}<br />MyObject.prototype.do_something_later = function () {<br />var self = this;<br />setTimeout(function () {<br />self._do_something()<br /> }, 1000);<br />}<br />
    18. 18. Async can make things hard<br />What I’ve typically done before:<br /> if ($user->requires_moderation()) { # makes a DB call<br /> … # moderate user<br /> }<br />What you have to do in Async style:<br />user.requires_moderation(function (err, flag) {<br /> if (err) { … }<br /> if (flag) {<br /> // moderate user<br /> }<br /> });<br />
    19. 19. Npmvs CPAN<br />Node Package Manager<br />(Obviously) a lot less stuff than CPAN<br />But still a surprising amount: 3831 packages as of writing<br />By default everything installs locally – no more screwing up apps by updating some library<br />For binary tools this still works. Binaries are symlinks to the install directory<br />Uploading is also much easier. “npm publish”. Done.<br />
    20. 20. Debugging<br />Basic debugger built in, pretty shit really<br />Node-inspector – plugs into WebKit’sJavascript debugger<br />
    21. 21. Profiling<br />Frankly, totally busted<br />Node-inspector has something but I can’t make it work<br />V8’s profiler is based on periodic snapshots, not a full profile<br />
    22. 22. Other nice parts<br />Methods can be (re)defined on the fly – makes per-object methods trivial<br />Try/catch and switch part of core language<br />Named methods/functions are just variables<br />function blah () { } === var blah = function () { }<br />blah // variable containing the function<br />blah() // call the function<br />object.blah() === object[“blah”]()<br />It’s much more pure OO than Perl<br />not very many global functions<br />string.lengthvs length($string)<br />
    23. 23. Node.js API<br />Timers, current process, Events, binary buffers, Streams, Crypto, Filesystem, Networking (IPv6 compatible), HTTP Server and client, Child processes, OS info<br />What’s Missing?<br />Cmdlinearg parsing<br />pack/unpack, flock, seek<br />Decent date/time manipulation<br />QuotedPrintable<br />Encode equivalent (iconv on NPM, but that lacks lots)<br />Test harness<br />
    24. 24. Example of filesystem access<br />Hard way:<br />fs.open(path, ‘r’, function (err, fd) {<br /> if (err) { ... }<br />varbuf = new Buffer(1024);<br />fs.read(fd, buf, 0, 1024, null, function (err, bytesRead, buf) {<br /> ...<br /> });<br />});<br />Easy way:<br />varrs = fs.createReadStream(path);<br />rs.on(‘error’, function (err) { ... });<br />rs.on(‘data’, function (buf) { ... });<br />Note: no line-by-line reading built in<br />
    25. 25. IPC coming in node 0.6<br />varcp = require('child_process');<br />// Note: not what we know as fork() in POSIX/Perl<br />var n = cp.fork(__dirname + '/sub.js');<br />n.on('message', function(m) {<br />console.log('PARENT got message:', m);<br />});<br />n.send({ hello: 'world' }); // uses JSON internally<br />// in sub.js:<br />process.on('message', function(m) {<br />console.log('CHILD got message:', m);<br />});<br />process.send({ foo: 'bar' });<br />
    26. 26. IPC with hook.io<br />Available via NPM<br />Does transparent message passing between multiple listeners<br />Kind of like gearman for node, but maybe more feature complete<br />
    27. 27. Using multiple CPUs<br />By default there’s no threading/forking<br />Needs a module – “cluster” from npm<br />var cluster = require(‘cluster’);<br />var net = require(‘net’);<br />varserver = net.createServer(function (client) {<br /> // handle client connection<br />});<br />var c = cluster(server);<br />c.listen(2525);<br />var net = require(‘net’);<br />varserver = net.createServer(function (client) {<br /> // handle client connection<br />});<br />server.listen(2525);<br />
    28. 28. Links:<br />http://nodejs.org/<br />http://npmjs.org/<br />https://github.com/baudehlo/Haraka<br />
    29. 29. Thank You<br />
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×