A COMMAND PROMPT TALK

85
A COMMAND PROMPT TALK

description

A COMMAND PROMPT TALK. Node.js and postgres. An Introductory Glance With Live Code, Later. 2010 AURYNN SHAW, COMMAND PROMPT INC. Hi!. What is Node.js. Fast Pure event-driven server-side javascript programming environment. Ew, javascript. Built on Google’s V8 - PowerPoint PPT Presentation

Transcript of A COMMAND PROMPT TALK

Page 1: A COMMAND PROMPT TALK

A COMMAND PROMPT TALK

Page 2: A COMMAND PROMPT TALK

Node.js and postgresAn Introductory Glance

With Live Code, Later

2010 AURYNN SHAW, COMMAND PROMPT INC.

Page 3: A COMMAND PROMPT TALK

Hi!

Page 4: A COMMAND PROMPT TALK

What is Node.js

Fast

Pure event-driven

server-side

javascript programming environment

Page 5: A COMMAND PROMPT TALK

Ew, javascript

Built on Google’s V8

Runs on modern unix-likes (Linux, OSX, Freebsd, Cygwin)

Speaks network natively, and easily (Hello world is in http!)

Ends up Similar to Python, Perl, Ruby, ETc.

Page 6: A COMMAND PROMPT TALK

Did I mention fast?

Single thread can do many thousands of connections

standard library doesn’t block

Page 7: A COMMAND PROMPT TALK

Did I mention fast?

Single thread can do many thousands of connections

standard library doesn’t block

Keeps the slow tasks from blocking

Keeps the quick tasks quick

Page 8: A COMMAND PROMPT TALK

blocking?

# Standard synchronous processingfh = open(“somefile”,”r”)contents = fh.read()# what if somefile is huge, 1GB+ ?print contents

Page 9: A COMMAND PROMPT TALK

Every step waits

Page 10: A COMMAND PROMPT TALK

How is node different?

Page 11: A COMMAND PROMPT TALK

Did I mention fast?

Single thread can do many thousands of connections

standard library doesn’t block

Keeps the slow tasks from blocking

Keeps the quick tasks quick

Page 12: A COMMAND PROMPT TALK

Really good for anything I/O

Page 13: A COMMAND PROMPT TALK

While slow tasks run, node carries on

Page 14: A COMMAND PROMPT TALK

Non-blocking!

fs.open(“somefile”, function (fd) { // When the file descriptor gets returned. var buffer = null;

fs.read(fd, buffer, length, position, function (e, bytes) {

// bytes read are here.// buffer will be not-null.

});});

Page 15: A COMMAND PROMPT TALK

As always, there’s caveats to this

Page 16: A COMMAND PROMPT TALK

Some caveats

node is entirely single-threaded

Event-driven programming is *really* different

Page 17: A COMMAND PROMPT TALK

A maze of callbacks

fs.open(“/tmp/hello”, function (fd) { var buffer = null;

fs.read(fd, buffer, length, position, function (e, bytes) {

// bytes read are here.// buffer will be not-null.

});});

Page 18: A COMMAND PROMPT TALK

Some caveats

node is entirely single-threaded

Event-driven programming is *really* different

Javascript’s prototype model is also really different

The syntax has warts

Page 19: A COMMAND PROMPT TALK

Build a bridge out of her?

/* This allows you to kind of inherit properly. */var o = function () {};var p = function () { /* Because ‘this’ changes */

var self = this;o.call(this);

};p.prototype = o;p.prototype.constructor = p;

Page 20: A COMMAND PROMPT TALK

So why is this important?

Page 21: A COMMAND PROMPT TALK

Why is it important?

Javascript owns the frontend

Page 22: A COMMAND PROMPT TALK

Why is it important?

Javascript owns the frontend

More jquery and javascript programmers every day

Page 23: A COMMAND PROMPT TALK

Why is it important?

Javascript owns the frontend

More jquery and javascript programmers every day

Javascript is fast

Page 24: A COMMAND PROMPT TALK

Faster every day

Page 25: A COMMAND PROMPT TALK

And now, we can use postgres!

Page 26: A COMMAND PROMPT TALK

When I got here...

postgres.js worked.

Page 27: A COMMAND PROMPT TALK

When I got here...

postgres.js worked.

Used the simple query protocol

Page 28: A COMMAND PROMPT TALK

When I got here...

postgres.js worked.

Used the simple query protocol

Used SQL escape to prevent injection attacks.

Page 29: A COMMAND PROMPT TALK

whyyyy

SOURCE: http://www.flickr.com/photos/striatic/2192192956/

Page 30: A COMMAND PROMPT TALK

But it did work!

Page 31: A COMMAND PROMPT TALK

And so I wanted to make it BETTER

Page 32: A COMMAND PROMPT TALK

So, I had to ask,

Page 33: A COMMAND PROMPT TALK

How do I not allow this?

Page 34: A COMMAND PROMPT TALK

Well...

Page 35: A COMMAND PROMPT TALK

to prepare a query

postgres.js Didn’t use libpq.

Page 36: A COMMAND PROMPT TALK

SOURCE: http://www.flickr.com/photos/tanaka/2319325408/

Page 37: A COMMAND PROMPT TALK

to prepare a query

postgres.js Didn’t use libpq.

Speaks pure protocol

Page 38: A COMMAND PROMPT TALK

to prepare a query

postgres.js Didn’t use libpq.

Speaks pure protocol

...So I had to learn the protocol.

Page 39: A COMMAND PROMPT TALK

Wax on, wax offMONTAGE!

Page 40: A COMMAND PROMPT TALK

Sadly, reality was a lot less exciting

Page 41: A COMMAND PROMPT TALK

Complexity Abounds

Simple protocol sends one message to pg

Easy to queue, internally.

Page 42: A COMMAND PROMPT TALK

QUERY

QUERY

QUERY

QUERY

QUERY

QUERY

RESULTS

REALLY SIMPLE MESSAGE QUEUE

Page 43: A COMMAND PROMPT TALK

Really, though

Simple protocol sends one message to PG

Easy to queue, internally.

Prepared statements require at least 5

Parse, describe, execute, bind, flush

Page 44: A COMMAND PROMPT TALK

SYNC

EXECUTE

BIND

DESCRIBE

PARSE

QUERY

QUERY

THIS TYPE OF QUEUE DOESN’T WORK

Page 45: A COMMAND PROMPT TALK

And while all this is happening

You cannot block the main thread

And postgres expects a synchronous request/response

But it does give responses...

Page 46: A COMMAND PROMPT TALK

And while all this is happening

You cannot block the main thread

Page 47: A COMMAND PROMPT TALK

And while all this is happening

You cannot block the main thread

And postgres expects a synchronous request/response

Page 48: A COMMAND PROMPT TALK

And while all this is happening

You cannot block the main thread

And postgres expects a synchronous request/response

But it does give responses...

Page 49: A COMMAND PROMPT TALK

So, we buffer message sets

Page 50: A COMMAND PROMPT TALK

SIMPLE

PREPAREDGROUP

SIMPLE

SIMPLE

PREPARED GROUP

SIMPLE

SIMPLE

KIND OF LIKE THIS

Page 51: A COMMAND PROMPT TALK

So we never block waiting for the DB

Page 52: A COMMAND PROMPT TALK

the application keeps responding

Page 53: A COMMAND PROMPT TALK

But that’s all a bit on the technobabbly side

SO

Page 54: A COMMAND PROMPT TALK

Let’s look codE!

Page 55: A COMMAND PROMPT TALK

Using postgres.js

/* Node setup */var pg = require(“lib/postgres-pure.js”), sys = require(“sys”);

var db = new pg.connect("pgsql://test:12345@localhost:5432/template1");

/* We now have a working DB handle. Or, we have an error. Either way.*/

Page 56: A COMMAND PROMPT TALK

Using postgres.js

/* We now have a working DB handle. *//* From here, we do: */

db.query(“select 1::int;”, function (err, rs) {// Wait, a function?console.log(sys.inspect(rs));

});

Page 57: A COMMAND PROMPT TALK

Why a function?

Page 58: A COMMAND PROMPT TALK

What’s going on here?

/* We now have a working DB handle. *//* From here, we do: */

db.query(“select 1::int;”, function (err, rs) {// Wait, a function?console.log(sys.inspect(rs));});

Page 59: A COMMAND PROMPT TALK

What you get

13// A little while later2

Page 60: A COMMAND PROMPT TALK

It’s happening asynchronously!

The function argument is what’s going to happen when the DB comes back

db.query returns immediately

and your app keeps on going!

Page 61: A COMMAND PROMPT TALK

this isn’t the cool bit

Page 62: A COMMAND PROMPT TALK

Prepared queries

/* Prepared queries work the same way */

db.prepare(“select ?::int as foobar;”, function (sth) {sth.execute(1, function (err, rs) {

console.log(sys.inspect(rs));});sth.execute(2, function (err, rs) {

console.log(sys.inspect(rs));});

});

Page 63: A COMMAND PROMPT TALK

Prepared queries

/* which will return */[ { foobar: 1 } ][ { foobar: 2 } ]

Page 64: A COMMAND PROMPT TALK

Or this!

/* This becomes a prepared statement behind the scenes*/db.query(“select ?::int as foobar;”,

1, // A single argumentfunction (err, rs) {

console.log(sys.inspect(rs));});

Page 65: A COMMAND PROMPT TALK

It would return

[ { foobar: 1 } ]

Page 66: A COMMAND PROMPT TALK

Sub-ideal Aspects

Page 67: A COMMAND PROMPT TALK

Bad, bad, bad.

postgres.js is still very alpha.

Node API is in flux

Learning Node takes a while

Page 68: A COMMAND PROMPT TALK

Cool bits!

Page 69: A COMMAND PROMPT TALK

Things that are pleasing

clean, perl DBI-based API.

Official support from Command prompt

Performance!

Page 70: A COMMAND PROMPT TALK

Vroom

[ananke:~/src/postgres-js] aurynn> time node benchmark.js 40000[ { count: 40001 } ]node benchmark.js 40000 18.85s user 2.75s system 87% cpu 24.602 total

Just over 2122 queries/second.

Page 71: A COMMAND PROMPT TALK

Some Stuff we can’t wait to add

Page 72: A COMMAND PROMPT TALK

Shiny things!

Notify support

Page 73: A COMMAND PROMPT TALK

PG notifications

/* Event-driven frameworks are ideal for this, and the notification setup can be handled behind the scenes.*/

db.on(“<NOTIFYNAME>”, function (payload) {// Do something useful as a result of // the notification from PG

});

Page 74: A COMMAND PROMPT TALK

Payload is also arbitrary data

Page 75: A COMMAND PROMPT TALK

Shiny things!

Notify support

Stability

Page 76: A COMMAND PROMPT TALK

Shiny things!

Notify support

Stability

Better error handling

Page 77: A COMMAND PROMPT TALK

Shiny things!

Notify support

Stability

Better error handling

More test cases

Page 78: A COMMAND PROMPT TALK

Shiny things!

Notify support

Stability

Better error handling

More test cases

Better type coercion

Page 79: A COMMAND PROMPT TALK

But the most important thing we’d like?

Page 80: A COMMAND PROMPT TALK

Users.

Page 81: A COMMAND PROMPT TALK

You guys. People who care.

Page 82: A COMMAND PROMPT TALK

So that’s postgres.js.

Page 83: A COMMAND PROMPT TALK

Any questions?

Page 84: A COMMAND PROMPT TALK

Okay. LIVE CODE!Shout out ideas!

Page 85: A COMMAND PROMPT TALK

https://github.com/commandprompt/postgres-js/

https://github.com/aurynn/postgres-js/

UNSTABLE

NOT QUITE AS UNSTABLE

FORK IT, AND HELP!