[00:00] ryah: (and by nothing, i mean null)
[00:00] felixge: so you could just do: error && throw error; ?
[00:00] felixge: on top of your function?
[00:00] ryah: i guess
[00:01] ryah: if (error) throw error;
[00:02] felixge: hm, I really hate single-line if statements, but yeah in theory that's what you could do
[00:03] felixge: this is certainly an interesting concept
[00:03] felixge: should be much simpler than promises, and also better performance wise
[00:03] ryah: http://gist.github.com/287389
[00:04] felixge: ryah: uhhh
[00:04] ryah: (does that even work?)
[00:04] felixge: that looks very nice
[00:04] felixge: I think it would work
[00:04] ryah: (using || ?)
[00:04] felixge: yes
[00:04] felixge: JS is awesome :)
[00:04] jed___: wouldn't it be better to put the error second?
[00:04] jed: that way you could make it optional.
[00:05] ryah: but a lot of callbacks have multiple params
[00:05] ryah: s/a lot/2/
[00:05] ryah: :)
[00:06] jed: ah, i see. why is this better than checking for typeof Error?
[00:06] jed: seems like it borks the intuitive arity.
[00:06] ryah: shrug - just playing around
[00:07] felixge: jed: it avoids a lot of "instanceof Error" typing :)
[00:07] felixge: jed: it would also allow throwing error values that are not instanceof error
[00:08] joshbuddy has joined the channel
[00:08] jed: i'd imagine it'd add to the overall typing, since by default most folks probably don't check for errors.
[00:09] felixge: jed: b/c you have to define the first error param?
[00:10] jed: yeah.
[00:10] jed: (not a big deal, clearly)
[00:10] felixge: jed: it would be a good way to encourage error checking :)
[00:11] jed: indeed! it just seems weird to have it come first.
[00:11] felixge: maybe, I find it familar from JS in the browser
[00:11] felixge: jQuery puts error events first sometimes, or at least has status == 'error'
[00:11] felixge: or something
[00:12] jed: can you give me an example?
[00:12] felixge: hm, I kinda hoped you wouldn't ask
[00:12] felixge: let me look
[00:12] felixge: :)
[00:12] jed: called your bluff!
[00:14] felixge: damn, guess I did make that up. Either way, in my fantasy version of jQuery it feels quite natural
[00:15] ryah: how about: if there is an error then it has to be returned - otherwise it throws an error
[00:16] felixge: interesting
[00:17] felixge: but that still makes your previous example more convoluted
[00:19] ryah: http://gist.github.com/287389
[00:20] felixge: ryah: wouldn't you already throw an error there if the first cat didn't succeed ?
[00:20] ryah: hmm, i guess that's not good. cause it still executes the second cat()
[00:20] jed: so returning an error is almost like another way of catching it?
[00:20] hassox: tbh the promise.js one reads better to me
[00:20] felixge: jedy
[00:21] felixge: hassox: yeah, but to be fair here - this is an example were it kinda excels this is why we're competing against it :)
[00:21] hassox: what do you mean that it excels?
[00:21] hassox: excels at what?
[00:22] felixge: I mean its very good at it
[00:22] hassox: not trying to dis it... just wanna know what the fuss is abouyt
[00:24] felixge: hassox: just playing with a different idea that jed brought up
[00:25] ropiku has joined the channel
[00:26] hassox: that is to return an error rather than emit it via the promise?
[00:31] jed: yeah, just exploring alternatives. i don't think any of us are too enamored of promises.
[00:34] eddanger has joined the channel
[00:35] hassox: jed can you explain to me the idea?
[00:35] hassox: sorry man
[00:35] hassox: I didn't pick it up from the scrollback
[00:36] isaacs has joined the channel
[00:37] binary42 has joined the channel
[00:37] jed: no prob. you should prolly read up on the archives starting yesterday at 23:31.
[00:38] jed: basically, thinking of alternatives to promises.
[00:38] jed: i couldn't really grok them, so i got rid of them in (fab).
[00:39] hassox: altogether?
[00:39] hassox: that's pretty cool :)
[00:39] jed: yeah, i just pass a response function. or as isaacs calls it, a stream.
[00:40] isaacs: jed: give ryah credit for the stream api
[00:40] jed: ha, sorry ryah!
[00:40] isaacs: he spec'ed it, i just implemented it. but the implementation in this case was pretty easy.
[00:41] jed: hassox: the idea is that using streams takes out a lot of overhead, and makes things more "pipeable".
[00:41] hassox: indeed
[00:41] hassox: streams are a fantastic idea I think
[00:41] hassox: ACTION is trying to work out how to use them properly
[00:43] jed: hassox: anyway, what we're playing around with is how errors fit into streams.
[00:43] hassox: i see
[00:43] jed: i'm of the opinion that everything should be thrown in. every stream takes only one argument. and handlers do what they do based on the argument passed.
[00:43] hassox: so if you have a stream that's piped through something to another stream, and the thing in the middle errors?
[00:44] isaacs: so, jsgi has a concept of an "error stream"
[00:44] isaacs: i'm not entirely sure what that means, but i figure it could just be a stream of error objects
[00:45] isaacs: after all, a stream is just a flow of thigns, there's no rule that says they HAVE to be strings.
[00:45] hassox: true
[00:45] jed: yeah, there's probably a CS-ey name for this, but i'm a fan of a single stream with type detection, instead of parallel/multiple streams.
[00:45] hassox: but an error should stop the thing yeah?
[00:45] isaacs: hassox: maybe. maybe not.
[00:45] isaacs: uncaught errors, certainly
[00:46] isaacs: and by default, there should probably not be catching. you can enable that with middleware if you want it.
[00:46] jed: yeah, i love functions as building blocks.
[00:46] hassox: so as you stream errors, the thing that actuall throws it is the first (default) error stream?
[00:46] jed: solves so many problems elegantly.
[00:46] isaacs: function catchingMiddleware (app) { return function (req) { try { var out = app(req); } catch (ex) { doSomething } finally { return out } } }
[00:46] hassox: and if you want to add a handler you just insert a new stream?
[00:47] isaacs: jed: one stream for input, one for output, and another for errors. it's worked in unix for years.
[00:47] hassox: isaacs: that's not going to catch much if ur app is async
[00:47] hassox: isaacs: that's true :D
[00:48] jed: isaacs: that's a good point.
[00:48] isaacs: right. you could probably just set up a global process.exceptionHandler
[00:48] isaacs: function catchingMiddleware (app) { process.exceptionHandler = doSomething; return app }
[00:48] hassox: isaacs: you could make that as an endpoint on the default error stream
[00:48] hassox: then things can highjack it if they want
[00:49] isaacs: yeah, there's a lot of options
[00:49] hassox: yeah that's pretty freaking sweet
[00:55] dekz has joined the channel
[00:56] jed_ has joined the channel
[00:56] r11t has joined the channel
[01:13] jed_ has joined the channel
[01:34] xxxss has joined the channel
[01:36] sudoer has joined the channel
[01:39] eddanger has joined the channel
[01:44] konobi: ryah: so how'd the closed hack session go?
[01:47] ryah: not well - it's a really terrible bug
[01:48] konobi: =0(
[01:48] konobi: in depth GC bug?
[01:49] ryah: i'm making some new object bindings and somehow they're leaking references (or something!) and getting collected
[01:51] ryah: konobi: have you used v8 at all?
[01:57] mikeal1 has joined the channel
[02:07] isaacs has joined the channel
[02:08] xxxss has left the channel
[02:10] joshbuddy has joined the channel
[02:32] softdrink has joined the channel
[02:46] TheHippo has joined the channel
[02:49] konobi: ryah: i've used chrome... does that count?
[02:51] TheHippo: because i didn't found anything reliable on the website of node.js and on the google group i want to ask if there are currently any developments for an mysql api?
[02:52] ryah: TheHippo: no
[02:52] TheHippo: hm... that's a pitty...
[02:52] ryah: TheHippo: i want to though :)
[02:53] ryah: i will use mysac library to do
[02:53] ryah: it
[02:55] TheHippo: never heard of it but it sound like the right thing for node.js
[02:57] jed: TheHippo: make sure you check out http://github.com/Guille/node.dbslayer.js/
[03:02] bpot has joined the channel
[03:02] konobi: ryah: valgrind wouldn't be of any help to you?
[03:04] eck has joined the channel
[03:04] eck: is there any support for mysql (or postgres) outside of the dbslayer stuff?
[03:05] konobi: there's node-postgres iirc
[03:05] eck: oh cool, see it now
[03:05] konobi: http://github.com/ry/node_postgres
[03:07] ryah: konobi: no- cause it's inside the vm
[03:09] konobi: ryah: looks like there re valgrind headers for v8
[03:10] ryah: konobi: where?
[03:10] konobi: http://v8.googlecode.com/svn/trunk/src/third_party/valgrind/valgrind.h
[03:11] fbparis has joined the channel
[03:11] fbparis: hello
[03:12] fbparis: ACTION is away: I'm away
[03:12] fbparis: ACTION is back (gone 00:00:00)
[03:12] ryah: konobi: cool - i didn't know you could hook in valgrind like that
[03:13] ryah: konobi: anyway - i've been running it through it - also using efence - no luck
[03:13] konobi: boo-urns
[03:14] fbparis: i'm not sure i've totaly understood the concept of javascript serverside :) but can you tell me if node.js could be an alternative to ape-project to set up a push server ?
[03:14] deanlandolt: fbparis: what's not to understand?
[03:16] fbparis: js is a scripting lang like any other, but it's strange to hear about js on the server :) i guess with a little experience it will be ok
[03:17] deanlandolt: python's a scripting lang...
[03:17] deanlandolt: ruby too...php...i hear they spend some time on servers :D
[03:17] fbparis: but i was also wondering some things for example, does that mean i could code easily a http parser which interprets javascript ?
[03:17] fbparis: yep, i'm coding essentially php / python now
[03:17] deanlandolt: http parser that interprets js? i'm not following
[03:18] stevestmartin has joined the channel
[03:18] konobi: you could write a http parser using javascript
[03:18] deanlandolt: fbparis: well, it turns out js can be significantly more peformant
[03:18] fbparis: yes, but is it more easy to create a kind a spider monkey ?
[03:18] deanlandolt: but that's the not reason to only use it
[03:19] deanlandolt: a kind of spidermonkey? you don't have to write a js parser...you just write js
[03:19] deanlandolt: you don't have to write an interpreter just to make serverside js work
[03:19] fbparis: mm, hard to explain
[03:20] fbparis: for example if in the html code of the web page, there's a javascript which set cookie
[03:20] deanlandolt: you want to handle and parse http? yeah, you can do that in js
[03:20] fbparis: can the server set the cookie ?
[03:20] deanlandolt: of course
[03:20] fbparis: it also could be used to create a snapshot of a page ?
[03:20] deanlandolt: node abstracts all the really low level socket details away
[03:21] binary42 has joined the channel
[03:21] steadicat has joined the channel
[03:21] deanlandolt: you just deal w/ the http request/response cycle by way of events...have a read of the api...http://nodejs.org/api.html
[03:21] konobi: fbparis: SSJS has bugger all concept of a browser... it's just a progamming language just the same as ruby, python, perl, etc...
[03:21] konobi: node has libraries available to let you interact with sockets, http, smtp, etc.
[03:22] fbparis: could create the dom tree of a web document in a cool way
[03:22] deanlandolt: fbparis: you could use other ssjs frameworks for that kind of thing -- ones that include a full dom implementation...but node (and its ilk) are just programming languages -- no nasty dom crap
[03:22] fbparis: ok :)
[03:23] fbparis: well my concerne actually is to find a choose a push server
[03:23] konobi: http://wiki.github.com/ry/node/modules
[03:23] fbparis: i've taken a look on ape-projetc and i wonder if they are other ways
[03:23] deanlandolt: yeah -- node's prety well suited to that
[03:23] konobi: fbparis: nginx push module... voila
[03:23] fbparis: thanx konobi
[03:24] ryah: ACTION <- braindead
[03:24] fbparis: and deanlandolt
[03:26] jed: hey, is there any documentation about shebang usage?
[03:26] ryah: no
[03:26] jed: ie, is it strictly platform dependent?
[03:26] jed: like, i need to point to the actual location of node
[03:26] jed: ?
[03:27] ryah: #!/usr/bin/env node
[03:27] jed: and that works on all platforms on which node is installed?
[03:27] ryah: yes
[03:27] ryah: (afaik)
[03:27] konobi: http://homepages.cwi.nl/~aeb/std/shebang/
[03:28] konobi: (a bit old... but useful)
[03:28] jed: konobi: thanks for that.
[03:28] deanlandolt: jed: it defintely has platform quirks
[03:29] jed: deanlandolt: i was worried about something like that.
[03:29] deanlandolt: ashb: ^^
[03:29] jed: right now i'm trying to think of a way to remove node boilerplate.
[03:29] jed: for example, this: http://gist.github.com/287475
[03:29] jed: i'd like to have the file simply have the (fab) definition and that's it.
[03:30] jed: and trying to think of the nicest way of doing that.
[03:30] deanlandolt: so you want to shebang in a script that shebangs node?
[03:30] jed: not necessarily.
[03:30] jed: i'd just like to have the (fab) file contain only fab logic.
[03:30] deanlandolt: plus a shebang line, right?
[03:31] jed: and then run a one-liner to specify the file and port and have it do the same as the gist.
[03:31] jed: the shebang is just one way of doing that, i guess.
[03:31] jed: i could also do $ node fab.js mysite.js -p 1234
[03:31] eck: what's wrong with passing them in as arguments?
[03:31] eck: i.e. sys.ARGV
[03:31] jed: eck: right, that's another option.
[03:32] jed: using a shebang would make it slightly shorter, is all.
[03:32] jed: but if it's platform-quirky, i'm not really interested.
[03:32] eck: shebang is just to specify which executable knows how to interpret the file
[03:32] eck: nothing more
[03:33] deanlandolt: depends on your usecase -- IIRC it was nesting shebangs that chokes linux
[03:33] jed: interesting.
[03:33] eck: on linux the shebang command can only have one argument
[03:33] eck: so you can do #!/usr/bin/env python
[03:33] eck: but not #!/usr/bin/env python -u
[03:33] scudco has joined the channel
[03:33] deanlandolt: eck: that's right...you coudln't do a reasonable arg list
[03:34] ryah: would be nice to have a -r cl option in node
[03:34] ryah: /usr/bin/env node -r /path/to/fab.js
[03:34] ryah: to require
[03:34] jed: oh, i see.
[03:35] jed: (sorry for my naivety, i'm not really a command-liner...)
[03:35] deanlandolt: narwhal uses the -r for require too
[03:36] deanlandolt: perhaps something to kick around in commonjs as a SecurableModules extension
[03:37] jed: so what do you think is the cleanest way currently to eval in node with a library pre-required?
[03:37] deanlandolt: my guess is cat+eval
[03:37] jed: so something like this? $ node fab.js myFile.js -p 1234
[03:38] eck: i don't know if there's a getopt for node.js, but if there is it would be pretty easy to parse something like the -r idea yourself
[03:38] eck: otherwise you could just scan for args ending in .js
[03:38] deanlandolt: there's a options parser in narwhal that should be pretty dep-free
[03:39] deanlandolt: plus someone tossed a link out to a node options parser
[03:39] eck: cool
[03:39] deanlandolt: but jed: did you mean $ node -r fab.js myFils.js -p 1234?
[03:39] jed: hmmm. that wouldn't actually work, right?
[03:40] deanlandolt: or were you thinking fab.js could just handle argv[1] as the file and pull it in
[03:40] jed: there's no file actually being evaluated, right?
[03:40] ryah: couldn't you just do something like
[03:40] ryah: #!/usr/bin/env node
[03:40] jed: i'm just looking for the cleanest way to have fab apps be simple files that look like "(fab)( ... my logic ... )(fab)
[03:40] ryah: fab = require('fab')
[03:41] ryah: require(process.ARGV[1]);
[03:41] jed: ryah: so that goes in fab.js?
[03:41] deanlandolt: i think you'd need a separate script for that
[03:42] deanlandolt: fab-start.js or something...otherwise what does require('fab') do?
[03:42] mikeal1 has joined the channel
[03:42] ryah: that'd be your fab.exec :)
[03:42] jed: i guess fab could sniff its environment too?
[03:43] jed: what if i require a file that has a shebang in it? will node barf?
[03:43] inimino: deanlandolt: it was OS X, not linux, that choked on chained shebang scripts
[03:43] deanlandolt: inimino: thanks...i was mixing up my shebang-lore
[03:43] jed: i can't type shebang without thinking of ricky martin. blarg.
[03:44] inimino: isaacs was doing something with that recently in the channel
[03:44] inimino: s/shebang/hash bang/g
[03:44] jed: inimino: yeah, i remember that... i wish the logs were searchable.
[03:44] inimino: ah, does Google index them?
[03:45] jed: "Your search - http://nodejs.debuggable.com/2010-01-21.html - did not match any documents. "
[03:46] inimino: ah
[03:46] fbparis: i think finaly i gonna try comet server with node.js :) thanx for your answers
[03:46] inimino: `g site:nodejs.debuggable.com
[03:46] gbot2: No Results
[03:47] inimino: ryah_Away: did you ever get your weird bug fixed?
[03:47] inimino: ryah_Away: I couldn't even reproduce it :/
[04:06] okito has joined the channel
[04:08] RayMorgan has joined the channel
[04:33] rtomayko has joined the channel
[04:35] cloudhead has joined the channel
[04:39] _sh has joined the channel
[04:44] softdrink has joined the channel
[05:11] eck: i just want to say that node.js is awesome
[05:11] eck: so much better than twisted
[05:14] rektide has joined the channel
[05:17] mikeal has joined the channel
[05:24] aguynamedben has joined the channel
[05:28] eck: i have a question about the impementation of the posix stuff
[05:28] eck: how is that implemented asynchronously? is there a thread that's spawned to do the syscall, and then the promise returns when the thread completes?
[05:31] kennethkalmer has joined the channel
[05:32] RayMorgan: eck: it uses libeio to handle async posix
[05:32] hassox: RayMorgan: does it actually work on winders?
[05:34] RayMorgan: I believe libieo does.. node currently doesn't. Believe that is slated for 0.2
[05:34] eck: oh, so on linux aio implements the full posix api?
[05:34] eck: i didn't realize that it did that
[05:36] RayMorgan: yeah: http://github.com/ry/node/blob/net2/deps/libeio/eio.c#L1556
[05:36] eck: hassox: it looks like windows has an aio api as well: http://wknight8111.blogspot.com/2009/05/aio-on-linux.html
[05:41] RayMorgan has joined the channel
[05:43] mattly has joined the channel
[06:00] hassox: ryah_Away: you there?
[06:00] hassox: oh bugger
[06:03] eck has left the channel
[06:12] inkubus08_ has joined the channel
[06:13] fbparis has left the channel
[06:15] micheil has joined the channel
[06:18] inkubus08_ has left the channel
[06:32] tlrobinson has joined the channel
[06:38] charles- has joined the channel
[06:43] mikeal has joined the channel
[07:02] RayMorgan: anyone know how many bytes the http response buffers before flushing?
[07:03] mikeal: i don't think the length is the only factor
[07:07] teemow has joined the channel
[07:07] joshbuddy_ has joined the channel
[07:14] Pilate: is there an appropriate way to catch a dns domain fail? http://pastebin.com/mc374f18 fails, as well as trying to addErrback
[07:17] Pilate: or not, i was doing it wrong
[07:19] paulca has joined the channel
[07:23] dekz has joined the channel
[07:25] sixtus42 has joined the channel
[07:34] zmoog has joined the channel
[07:35] dekz_ has joined the channel
[07:41] scudco has joined the channel
[07:50] dekz has joined the channel
[07:51] dekz has joined the channel
[07:54] dekz has joined the channel
[07:58] dekz has joined the channel
[08:00] kennethk_ has joined the channel
[08:08] eck has joined the channel
[08:12] micheil has joined the channel
[08:13] scudco has joined the channel
[08:26] felixge has joined the channel
[08:28] mikeal1 has joined the channel
[08:56] ayo has joined the channel
[08:57] brandon_beacher has joined the channel
[08:57] aho has joined the channel
[08:57] sztanpet has joined the channel
[08:57] bjartek has joined the channel
[08:57] mediacoder has joined the channel
[08:57] erikcorry|away has joined the channel
[08:57] RJ2 has joined the channel
[09:02] johan-s has joined the channel
[09:04] teemow has joined the channel
[09:31] isaacs: the logs are searchable. wget + grep.
[10:14] kennethk_ has joined the channel
[10:15] hassox has joined the channel
[10:43] markwubben has joined the channel
[10:45] rolfb has joined the channel
[10:48] sixtus42 has joined the channel
[11:05] jfd has joined the channel
[11:09] rolfb has joined the channel
[11:42] jfd has joined the channel
[11:43] joshbuddy has joined the channel
[11:44] felixge has joined the channel
[11:57] blackdog` has joined the channel
[12:01] charlenopires has joined the channel
[12:08] micheil has joined the channel
[12:09] moosecrumpet has joined the channel
[12:10] micheil has joined the channel
[12:16] charlenopires has joined the channel
[12:16] brandon_beacher has joined the channel
[12:16] sztanpet has joined the channel
[12:16] bjartek has joined the channel
[12:16] mediacoder has joined the channel
[12:16] erikcorry|away has joined the channel
[12:22] kennethkalmer has joined the channel
[12:45] alex-desktop has joined the channel
[12:46] jfd1 has joined the channel
[13:03] jfd has joined the channel
[13:39] tlynn has joined the channel
[13:40] tlynn: I've just come across a bug in http.js: it retries indefinitely if the server opens the connection but sends no headers (e.g. connecting to the wrong port)
[13:40] felixge: tlynn: http client?
[13:41] jspiros has joined the channel
[13:41] tlynn: yep
[13:41] emyller_ has joined the channel
[13:41] [k2]_ has joined the channel
[13:41] martyn__ has joined the channel
[13:41] skampler has joined the channel
[13:41] tlockney_ has joined the channel
[13:41] jacobat has joined the channel
[13:41] felixge: tlynn: can you whip up a test case?
[13:41] micheil: tlynn: I can't see this
[13:42] Pilate has joined the channel
[13:42] tlynn: ok, will try
[13:44] micheil: do you mean createServer or createConnection?
[13:45] tlynn: I mean createClient
[13:46] tlynn: if you connect a client to a server that doesn't send http headers
[13:46] tlynn: ... hmmm
[13:46] tlynn: no, it's something subtler than that
[13:47] tlynn: will carry on looking into it.
[13:49] tlynn: I think it's looping at lib/http.js:471 anyway, but I'll try to narrow down the circumstances
[13:50] tlynn: ah, I think the server drops the connection after receiving the GET / HTTP/1.1 line
[13:51] tlynn: so the problem is that that isn't being treated as an error in the client
[13:52] tlynn: actually I'm not sure under what circumstances (if any) that reconnect logic should be invoked
[13:53] lifo has joined the channel
[13:53] kriszyp has joined the channel
[14:10] un0mi has joined the channel
[14:11] mahemoff has joined the channel
[14:16] micheil has joined the channel
[14:17] rtomayko has joined the channel
[14:25] cloudhead has joined the channel
[14:34] davidsklar has joined the channel
[14:51] n8o has joined the channel
[14:55] cloudhead has joined the channel
[14:57] bryanl has joined the channel
[15:13] Booster has joined the channel
[15:28] sixtus42 has joined the channel
[15:34] alexiskander has joined the channel
[15:36] softdrink has joined the channel
[15:43] okito has joined the channel
[15:49] charlenopires has joined the channel
[15:51] qFox has joined the channel
[15:53] kennethk_ has joined the channel
[16:01] kenneth__ has joined the channel
[16:05] jcrosby has joined the channel
[16:05] kennet___ has joined the channel
[16:07] binary42 has joined the channel
[16:15] teemow has joined the channel
[16:16] kriszyp_ has joined the channel
[16:20] steadicat has joined the channel
[16:25] ryah: hassox: hey
[16:32] tlynn: http://paste.pocoo.org/show/170693/ <-- permanently reconnecting http client
[16:34] tlynn: is that supposed to happen?
[16:37] ryah: hm
[16:37] ryah: nope
[16:42] around has joined the channel
[16:42] tlynn: [13:46] I think it's looping at lib/http.js:471
[16:43] tlynn: but I'm not sure what the reconnection logic there is supposed to be doing
[16:49] joshbuddy has joined the channel
[16:50] ryah: it's a good example.
[16:50] ryah: something's wrong
[16:50] tlynn: glad we've got that much sorted :-)
[16:56] sudoer has joined the channel
[17:06] bryanl has joined the channel
[17:14] eddanger has joined the channel
[17:19] jamiew has joined the channel
[17:20] tlynn: I suspect it should be doing requests.shift() to pop requests before attempting to connect them
[17:21] jamiew has left the channel
[17:21] tlynn: thus avoiding the need for the strange "opening" check in http.js:471
[17:22] isaacs has joined the channel
[17:23] ryah: tlynn: here is a cleaned up test http://gist.github.com/288020
[17:23] ryah: it goes in test/mjsunit
[17:26] bpot has joined the channel
[17:28] jed has joined the channel
[17:29] tlynn: Thanks. I've not tried the test stuff, but first I'll work on fixing the problem before trying to integrate the test for it.
[17:30] tlynn: I don't understand http.js line 437, "if (req == requests[0]) flushMessageQueue(client, [req]);", when would someone ever enqueue the same request twice?
[17:32] ryah: ACTION thinks he has a fix
[17:32] tlynn: cool
[17:32] ryah: nevermind
[17:33] ryah: oh - nevermind again
[17:33] ryah: seems to work
[17:33] ryah: just running the full tests
[17:36] CIA-75: node: 03Ryan Dahl 07master * r30b0522 10/ test/mjsunit/test-http-client-reconnect-bug.js :
[17:36] CIA-75: node: Bugfix: HTTP client automatically reconnecting
[17:36] CIA-75: node: Test case by tlynn. - http://bit.ly/9jct9w
[17:39] scudco has joined the channel
[17:42] isaacs: ryah: you get a chance to look at my http sendHeader patch?
[17:42] jcrosby has joined the channel
[17:42] ryah: isaacs: uh? maybe i didn't see it
[17:42] ryah: oh right
[17:43] isaacs: ryah: http://groups.google.com/group/nodejs/browse_thread/thread/76ccd1714bbf54f6#
[17:43] isaacs: i was going to say, though, if you do want it, you might want to hold up.
[17:43] isaacs: i want to go through and make sure that it also supports the way(s) that JSGI specs headers.
[17:44] isaacs: it'll make the streaming/evented JSGI an easier pitch.
[17:44] deanlandolt: isaacs: sweet
[17:44] ryah: how does jsgi spec headers?
[17:44] deanlandolt: though it looks like it already supports jsgi
[17:44] deanlandolt: {"key" : ["val", "val2"]}
[17:45] deanlandolt: or {"key" : "val1"}
[17:45] joshbuddy has joined the channel
[17:45] deanlandolt: the former meaning multiple header lines of "key"
[17:45] isaacs: yeah
[17:46] isaacs: deanlandolt: wasn't there also some concept of doing something like [ {key:"val"}, {key2:"val"}, ..]
[17:46] kriszyp has joined the channel
[17:46] isaacs: or did that get shut down?
[17:46] deanlandolt: i don't remember that...AFAIR headers has always been an obj
[17:46] isaacs: also, i want to make it actually check for forEach and toString
[17:47] isaacs: since jsgi apps might do something silly like { myHeader : { toString : function ... }}
[17:47] deanlandolt: i don't quite understand what value you get by having headers be a list
[17:47] isaacs: deanlandolt: you can proxy them in the exact same order that they came in.
[17:47] deanlandolt: ah that's right
[17:47] kriskowal has joined the channel
[17:47] isaacs: but i've yet to find a case where that matters. if you have multiple headerA fields, then they must be in order, but if you have headerA and headerB, it doesn't matter which comes first.
[17:48] isaacs: ryah: apparently, it does it the way that my patch does :)
[17:48] deanlandolt: yeah -- i'm fairly certain the spec says something about how it's nice to go from general to specific but it's definitely not a mandate
[17:48] isaacs: i just need to make it a little stricter wrt toString and forEach
[17:49] deanlandolt: plus, just like with header case names, you can always provide the server with a map for that
[17:49] charlenopires has joined the channel
[17:49] isaacs: ACTION has been using lowercase header field names for years with no complaints.
[17:49] deanlandolt: heh...awesome
[17:49] isaacs: some servers are whiny about it, though.
[17:50] isaacs: but, when i set headers in my code, it's generally always lowecase.
[17:50] deanlandolt: but i'm not even worried because nothing stops servers from case-correcting or allowing users to specify an exact correction map or fn
[17:50] isaacs: right
[17:50] deanlandolt: but in going through and updating jack the vast majority of what i was doing is ripping out a bunch of HashP.includes/get/put calls
[17:50] deanlandolt: no longer necessary...it was awesome
[17:51] isaacs: srsly.
[17:51] isaacs: it seems like the HashP stuff would be faster and only slightly less space-efficient if it kept an lcase map of existing field names for each obj.
[17:52] trodrigues has joined the channel
[17:52] isaacs: anyway, i figure that's a yak that i'll shave when he comes in for his appointment. no reason to go chasing him down if he'd prefer to be furry.
[17:53] fictorial has joined the channel
[17:53] deanlandolt: that's an interesting metaphor
[17:53] konobi: orlandov: playing with riak now?
[17:53] robrighter has joined the channel
[17:54] tlynn: jsgi allowing both {"key": "val"} and {"key" : ["val", "val2"]} is a recipe for disaster.
[17:54] isaacs: tlynn: it's working pretty well.
[17:54] deanlandolt: tlrobinson: why?
[17:54] isaacs: what do you find to be disastrous about it?
[17:54] deanlandolt: err...damn completion...tlynn
[17:55] ryah: wow: http://twitter.com/AndyMaleh/statuses/8286650327
[17:56] isaacs: ryah: ha!
[17:56] isaacs: didn't EventMachine come like, way before node.js?
[17:56] tlynn: people are going to write code that expects one which will occasionally do weird stuff when it gets the other
[17:56] davidsklar: another example of "the future is here but is just not widely distributed, yet" :)
[17:56] isaacs: tlynn: all that's needed is a bit of setHeader/getHeader sugar.
[17:56] isaacs: it's not too hard, really
[17:56] ryah: isaacs: yeah
[17:57] deanlandolt: i hear those python folks are working on a node clone called "twisted" or something
[17:57] davidsklar: deanlandolt: hehehe
[17:57] isaacs: oh, and there's another thing, probably based on node, i think. another c project. what's it called.... engine something?
[17:57] isaacs: xman?
[17:57] deanlandolt: tlynn: then test for it...but interestingly arrays coerce "correctly" according to rfc 2616
[17:58] tlynn: actually I was thinking last night that an nginx rewrite in node.js would be a handy thing
[17:58] deanlandolt: kinda a weird but really cool property...yes, i know it doesn't work for cookies, but that's about all i know of
[17:58] isaacs: tlynn: nothings stopping an app from doing foo:["bar"] for headers, if you prefer to always use arrays.
[17:58] isaacs: but, if you want to ADD a header, you have to check anyhow.
[17:58] tlynn: isaacs: I'd prefer the standard to always use arrays
[17:58] isaacs: it's kind of a necessary evil.
[17:58] konobi: tlynn, that seems kinda useless... nginx is _awesome_
[17:59] tlynn: konobi: in my tests, it was significantly slower than node.js
[18:00] felixge: ryah: maybe github is screwing with me, but all I see is a test case, not a fix: http://github.com/ry/node/commit/30b0522157069360615402651d6b98c9397dfc19
[18:00] deanlandolt: tlynn: so if you always used arrays, don't you still have to test before you try to push a header?
[18:00] konobi: hhhmmm... after seeing it used in production in one of the highest trafficed sites in europe... i'm pretty sure it's faster
[18:00] tlynn: deanlandolt, it's the readers I worry about
[18:00] ryah: felixge: oh thanks
[18:01] CIA-75: node: 03Ryan Dahl 07master * r1bb5294 10/ lib/http.js : Forgot to include fix from HTTP client bug (30b0522) - http://bit.ly/cac4gJ
[18:01] deanlandolt: tlynn: what about them? can you give me an example where it'd be too wonky?
[18:01] tlynn: konobi: could be, but I couldn't get it load balancing more than 4k req/s while the node.js backend was serving 12.5k
[18:01] felixge: konobi: I guess node will have a hard time beating nginx for serving static files. I do think there could be shot at serving large static files. But as far as dynamic content is concerned, node will always beat some FCGI shit
[18:02] johan-s has joined the channel
[18:02] felixge: tlynn: what did you try to serve with nginx?
[18:02] tlynn: felixge: "hello world" served with node.js
[18:02] felixge: tlynn: probably bad config, what os did you test?
[18:02] orlandov: konobi: i played around with it a little bit last night
[18:02] tlynn: just using nginx to load balance
[18:03] tlynn: linux, using epoll
[18:03] felixge: Node being 3x faster than nginx sounds like defying the laws of physics
[18:03] felixge: ;)
[18:03] isaacs: yeah, in my tests nginx gets up to around 20k q/s
[18:03] orlandov: konobi: but it's missing javascript mapreduce, indexes or arbitrary queries
[18:03] orlandov: s/or/and/
[18:03] konobi: yeah, it's a seperate project iirc
[18:03] tlynn: that sounds more like what I was expecting. sounds like I need to get some of you to debug my nginx config then :-)
[18:03] isaacs: orlandov: right, it's not javascript. that's a HUGE mark in node's favor.
[18:03] isaacs: tlynn: ^_^
[18:04] felixge: either way, v8 is probably the fastest dynamic language implementation on the planet so we should all be happy campers :)
[18:06] tlynn: felixge: I bet gforth kicks its ass ;-)
[18:06] davidsklar has joined the channel
[18:06] isaacs: felixge: from what i've heard, tracemonkey and sfx both beat it.
[18:07] isaacs: felixge: or at least, that's what mozilla and apple say.
[18:07] felixge: maybe I should restate it to "dynamic languages I heard about before and would consider using" : )
[18:07] isaacs: hehe
[18:07] felixge: well, none of their browsers particularly impress me
[18:07] tlynn: and there's always lisp :-)
[18:07] konobi: the opera JS VM is kicking everyone's ass at the moment
[18:08] jamiew_ has joined the channel
[18:08] orlandov: where are people seeing these performance numbers?
[18:08] felixge: ACTION remembers he shouldn't have brought this up, benchmarking languages is probably even harder than implementing those languages to begin with
[18:09] tlynn: ryah: that commit doesn't fix the client.readyState!="opening"
[18:09] tlynn: which I'm still very skeptical about
[18:09] jamiew_ has left the channel
[18:09] hober has joined the channel
[18:09] ryah: tlynn: hm?
[18:10] tlynn: http.js:473 - what's that client.readyState!="opening" doing there?
[18:10] tlynn: it looks like potential for a blocked queue to me
[18:10] konobi: orlandov: http://lifehacker.com/5432054/opera-105-pre+alpha-is-all-about-speed-and-private-browsing
[18:11] tlynn: in the case where a request closes in the opening state
[18:11] ryah: tlynn: opening = resolving
[18:11] felixge: konobi: that picture tells a story
[18:11] tlynn: yes, but still.
[18:12] ryah: tlynn: that code could be better written. it's hard to follow
[18:12] ryah: but there is another client.connect
[18:12] ryah: 427
[18:12] felixge: konobi: one of these "Hey, we are going to improve performance by optimizing to win this benchmark"-stories
[18:12] felixge: :)
[18:13] konobi: felixge: *shrug* the opera guys are smart cookies
[18:13] orlandov: felixge: though to be fair, every vendor does that
[18:14] tlynn: ryah: ok, so what happens if a request closes while resolving? or is the close event never emitted while resolving?
[18:15] felixge: orlandov: maybe, but it almost destroys the value in publishing stuff like that
[18:15] konobi: right now... it's fast _enough_ you're bottlenecks aren't going to be in the VM... it'll be I/O
[18:15] aguynamedben1 has joined the channel
[18:15] orlandov: felixge: oh i completely agree
[18:15] rictic has joined the channel
[18:15] orlandov: just saying :)
[18:16] felixge: I wish those benchmarks would start out with collecting data about real world javascript usage to weigh in the different aspects
[18:16] ryah: tlynn: hm, not sure
[18:16] felixge: but since that would actually be a ton of freaking work, nobody does it
[18:16] felixge: :)
[18:17] blackdog` has joined the channel
[18:18] felixge: anyway, in general I love the fact that all those companies are spending their budgets on JS engines :)
[18:18] orlandov: totally
[18:18] tlynn: Google may have a little budget left to spend
[18:18] orlandov: and i think we're going to see a lot of convergence as these engines shake out
[18:19] felixge: yeah, they'll squeeze out the last drips of performance
[18:19] felixge: unlike ruby where everybody seems to talk about faster implementations but very little has come out of it so far :)
[18:19] orlandov: haha
[18:20] orlandov: poor slow ruby
[18:21] tlynn: no language that uses dollar signs ever goes fast :-)
[18:21] konobi: yeah, javascript is _so_ slow
[18:22] isaacs: you know, it's not so much important to have a fast VM. it's important to have a VM that is several orders of magnitude faster than your other factors involved.
[18:22] felixge: tlynn: you mean PHP?
[18:22] felixge: isaacs: amen
[18:23] tlynn: perhaps I should say relies on dollar signs
[18:23] isaacs: at this point, whether you're using v8 or tracemonkey or whatever, on the server, it kinda doesn't matter as much as how you write your code and how you handle concurrency and connections.
[18:23] tlynn: jQuery only uses $ because no-one else did
[18:23] isaacs: tlynn: didn't prototype grab that first?
[18:24] tlynn: well maybe, but for the same reason
[18:26] jcrosby has joined the channel
[18:26] tlynn: compared to PHP, Perl and Ruby, javascript doesn't use $.
[18:26] konobi: ruby doesn't use $
[18:27] konobi: it can... but i generally never see it
[18:27] orlandov: i thought $ was a scoping sigil
[18:27] orlandov: globals?
[18:27] orlandov: $
[18:27] tlynn: I'd read the language spec, but there isn't one :-)
[18:28] konobi: ACTION goes back to hacking some perl
[18:29] cmlenz has joined the channel
[18:30] tlynn: I read that this is all meaningful in ruby: $! $@ $_ $. $& $~ $= $/ $\ $0 $* $$ $?
[18:30] orlandov: perl too
[18:30] isaacs: and most of that in bash, too
[18:31] orlandov: in fact, most of those
[18:31] tlynn: some language designers can't recognise a legacy issue when they see one
[18:33] tlynn: anyway, ryah: are you still looking at that case, or should I?
[18:45] ryah: nope
[18:45] ryah: if you find something i'll fix it hough :)
[18:45] jcrosby has joined the channel
[18:49] felixge: ryah: what tiling window managers?
[18:50] ericflo has joined the channel
[18:50] ryah: felixge: ipad
[18:50] felixge: ryah: I thought you might be the only person not watching this :)
[18:50] b0bg0d has joined the channel
[18:51] ryah: felixge: i'm not - i'm just getting bombarded with talk about it from various chat channels :)
[18:52] felixge: ryah: so far nothing you'd regret to have missed anyway :)
[18:52] deanlandolt has joined the channel
[18:52] felixge: its a big iphone that will be awkward to use for phone calls :)
[18:54] stephenlb has joined the channel
[18:54] quirkey has joined the channel
[18:57] isaacs: jesus christ, you guys are talking about the ipad?
[18:57] isaacs: it's everywhere.
[18:58] orlandov: isaacs: i'm not!
[18:58] orlandov: everyone at my work is talking about it.. ugh
[18:58] ryah_away: yes *groan*
[18:58] ryah_away: bbl
[18:59] felixge: isaacs: sorry, I thought ryah found some new tiling window manager so I was curious :)
[18:59] isaacs: hehe
[19:05] tlynn: ryah: ugh the http connection state machine is painful to follow
[19:06] jcrosby has left the channel
[19:06] around: ipad
[19:06] around: ipad
[19:07] around: w00t woot
[19:11] felixge: tlynn: yeah
[19:11] felixge: I've actually played with generic patterns for state machines in JS a while back
[19:11] felixge: its kind of hard to do more complex stuff without getting into a mess of event emitters and weird logic jumps right now
[19:11] felixge: (and by hard I mean that I usually screw it up )
[19:11] felixge: :)
[19:12] felixge: but I haven't had a reason to complain about the http module much in the past, it works pretty well for me
[19:12] eck has joined the channel
[19:14] paulca has joined the channel
[19:15] tlynn: hmm, actually I realise it's the more general node_net.cc that I'm looking at
[19:16] tlynn: anyone want to tell me where I find the definition of eio_req?
[19:17] tlynn: aha, eio.h :-)
[19:21] tlynn: node_net.cc:324 - mysterious r variable is never read
[19:30] tlynn: this is brain melting. Connect triggers AfterResolve which calls Connect again
[19:39] tlynn: nope, I can't see how it escapes that loop
[19:44] tlynn: Connection::Resolve breaks the contract expressed in the comment immediately above it
[19:45] tlynn: (node_net.cc:294)
[19:48] isaacs: is there any kind of md5 or sha1 type thing in javascript?
[19:49] deanlandolt: isaacs: http://github.com/280north/narwhal/blob/master/lib/md5.js
[19:49] isaacs: kewl
[19:49] isaacs: lulz: ipad.concat(struct.str2binl(data)
[19:49] deanlandolt: and http://github.com/280north/narwhal/blob/master/lib/sha.js (there are toehrs too)
[19:50] deanlandolt: heh
[19:50] deanlandolt: look pretty dep-free -- just struct and util (w/ kriskowal wants to pull out and put in its own package anyway)
[19:50] RayMorgan has joined the channel
[19:51] tlrobinson has joined the channel
[19:51] isaacs: yeah, what's binb2bin and strb2bin stuff.
[19:51] isaacs: ?
[19:53] tlynn: suspected http.js bug: if you have multiple connection attempts queued on an http client and one of them errors (or name resolution/connection fails), the others aren't attempted (I think)
[20:01] RayMorgan has joined the channel
[20:01] technoweenie has joined the channel
[20:09] jacobolus has joined the channel
[20:15] b0bg0d1 has joined the channel
[20:16] jed has joined the channel
[20:16] mikeal has joined the channel
[20:41] jcrosby has joined the channel
[20:44] deanlandolt: isaacs: binb2bin: Convert an array of big-endian words to a string
[20:44] isaacs: deanlandolt: k, cool
[20:44] isaacs: thanks
[20:44] deanlandolt: it's all in http://github.com/280north/narwhal/blob/master/lib/struct.js
[20:44] isaacs: yeah, i saw that, but got distracted.
[20:45] deanlandolt: i just noticed that struct has a binary requirement...ugh
[20:45] isaacs: yeah
[20:45] deanlandolt: it'll be awesome when we can solidy a Binary proposal...though now that there's an es-next proposal being batted around it'll probably hold it up even longer
[20:45] isaacs: deanlandolt: so, it's looking like, by the end of the week, the diff between jsgi 0.3 and ejsgi will be just the body streams.
[20:46] deanlandolt: that's ridiculous
[20:46] isaacs: yeah, that too.
[20:46] deanlandolt: perhaps we could propose ejsgi as a jsgi extension
[20:46] isaacs: i'd like to change the name, maybe.
[20:46] isaacs: though, i guess, the stream is an evented stream as opposed to a java-style nio stream.
[20:47] deanlandolt: i don't see the real problem with that...it can be supported (by fully buffered) on any platform with an event loop construct
[20:48] deanlandolt: s/buffered/buffering
[20:48] deanlandolt: and in most cases (maybe all) buffering would be unnecessary (right?)
[20:50] isaacs: sure
[20:51] deanlandolt: i may be missing something but that just feels like the right solution
[20:53] jed: (i wonder if there's a less overloaded word than stream?)
[20:53] isaacs: jed: not sure.
[20:56] deanlandolt: jed: it'd be nice...the word "event stream" seems pretty descriptive to me though
[20:56] jed: deanlandolt: i agree... the word event is key.
[20:57] paulca has joined the channel
[20:57] deanlandolt: but i guess "event stream" is kinda overloaded by other disciplines
[20:57] jed: i mean, jsgi as it stands calls them streams, and they're very different.
[20:58] deanlandolt: true...but i'd kinda like to change that if possible
[20:58] deanlandolt: the input stream is problematic for a lot of reasons
[20:59] mikeal: i think it's just generically adapted from wsgi isn't it?
[20:59] deanlandolt: by way of rack, yeah
[20:59] mikeal: WSGI requires an input stream which is a reference to Python file-like objects
[21:00] deanlandolt: yeah, stringIO stuff
[21:00] mikeal: i think techinically StringIO doesn't implement all the necessary methods
[21:00] deanlandolt: rack requires a rewind, which is even worse than jsgi
[21:00] mikeal: but the spec outlines what are the required methods
[21:02] isaacs: well, there's no reason why jsgi needs to be exactly like rack or wsgi
[21:02] isaacs: there are plenty of differences already.
[21:02] isaacs: we can specify what a "Stream" means, and then that's what it'll mean.
[21:02] deanlandolt: agreed...it's good to stay aligned where there's no benefit to diverging
[21:03] deanlandolt: exactly
[21:03] isaacs: right
[21:03] isaacs: this is a case where diverging pays the bills, i think.
[21:03] mikeal: define stream as something that implements specific methods/events
[21:03] isaacs: right
[21:03] isaacs: and anything with an event loop can implement that spec.
[21:03] deanlandolt: yep
[21:04] isaacs: the tricky stuff comes up when we have to spec "Event"
[21:04] mikeal: honestly, i would just define EventEmitter
[21:04] mikeal: in terms of it's default methods
[21:05] mikeal: start with that, and see if anyone from non-node.js implementations take issue with it
[21:05] jcrosby has joined the channel
[21:06] mikeal: i think the only people that might be pissy are dojo people, because their event model supports stop-propagation if I remember correctly
[21:07] isaacs: mikeal: well, ideally, we'd only spec as much as absolutely necessary.
[21:07] isaacs: ie, what you MUST implement to be able to take this ejsgi app and use it over there.
[21:08] isaacs: just addListener, really.
[21:08] deanlandolt: exactly
[21:08] mikeal: specs only grow in size, never decrease, it's one of the worst realities of spec writing
[21:08] isaacs: since you shouldn't be calling emit() directly.
[21:08] deanlandolt: and the two events to raise (data and eof)
[21:08] isaacs: mikeal: that's why they have to start small!
[21:08] isaacs: deanlandolt: right
[21:08] mikeal: definitely
[21:09] isaacs: but we also have to spec what happens when you add more than one handler
[21:09] deanlandolt: why?
[21:09] isaacs: because that will happen.
[21:09] deanlandolt: it shouldn't
[21:09] isaacs: it's either a queue, a stack, a single callback assignment, or a single write-only callback assignment
[21:09] deanlandolt: if you want to read into you've got to have a stream to write out to
[21:09] isaacs: i might not want to filter, though, just wath.
[21:09] isaacs: watch
[21:09] mikeal: can the event alter the value?
[21:09] deanlandolt: true
[21:10] isaacs: mikeal: no. you'd have to hijack and return a new stream to do that
[21:10] isaacs: .
[21:10] isaacs: at least, if you're streaming strings, anyhow.
[21:10] mikeal: so you can't write gzip compression with this spec?
[21:10] isaacs: mikeal: sure you an
[21:11] deanlandolt: mikeal: you can, you just have to write it to a new stream
[21:11] mikeal: oh i see what you're doing
[21:11] deanlandolt: and you return the new stream
[21:11] isaacs: the middleware just has to grab the output stream from the app, gzip it in bits, and return a new gzipped stream
[21:11] mikeal: wait wait
[21:11] mikeal: those sounded slightly conflicting
[21:12] deanlandolt: how so?
[21:12] mikeal: can I iteratively gzip without taking the entire response in to memory?
[21:12] deanlandolt: yes
[21:12] mikeal: ok
[21:12] isaacs: mikeal: you can do whatever you want with the stream
[21:12] isaacs: buffer it, don't buffer it, etc.
[21:12] deanlandolt: but you shouldn't have to buffer to gzip
[21:12] mikeal: you do want to buffer a little if you're going to be efficient
[21:12] deanlandolt: you may want to to make it a more effective encoding
[21:12] mikeal: you also need the length to be efficient
[21:13] deanlandolt: err, you still don't have to buffer...let me be a little clearer...
[21:13] deanlandolt: you have a gzip middlewar.e..
[21:13] mikeal: don't HAVE to
[21:13] isaacs: mikeal: yeah, you have to buffer just until you have some reasonably sized chunk.
[21:13] isaacs: s/have/ought/
[21:13] mikeal: i get it
[21:14] mikeal: it was just the wording that confused me for a minute
[21:14] isaacs: if the app is streaming one byte at a time, then that'd be stupid to try to gzip each byte independently, since your line length isnil.
[21:14] deanlandolt: but an evented stream also makes it much more efficient to do something like content-length middleware
[21:14] deanlandolt: and all that good stuff
[21:15] mikeal: topical question
[21:15] mikeal: how will this work on my iPad :)
[21:15] mikeal: haha
[21:15] deanlandolt: ACTION bangs head against desk :D
[21:17] jacobolus has joined the channel
[21:18] teemow has joined the channel
[21:19] jed: deanlandolt: i just wrote that, heh: http://gist.github.com/287475#file_hello_middleware.js
[21:20] deanlandolt: damn that's small
[21:20] technoweenie: what is fap
[21:20] technoweenie: fab
[21:20] jed: you had me at fap.
[21:20] deanlandolt: hard for me to follow w/ all the positional arguments but wow that's elegant
[21:20] jed: the middleware looks like isaacs envisioned: http://gist.github.com/273982
[21:21] jed: not sure what you mean by positional, tho.
[21:21] isaacs: jed: i'm glad that gist isn't going to waste ;)
[21:22] jed: yeah, i decided that calling fab with a function should be used for middleware, not binding, since the former is so much moresexy.
[21:22] jed: i'm launching (fab) officially soon at fabjs.org, as soon as i can figure github pages out.
[21:23] deanlandolt: jed: sorry, positional's the wrong word...just not sure what things imply
[21:23] deanlandolt: especially w/ the chianing
[21:23] jed: ah, sure.
[21:23] deanlandolt: * chaining
[21:23] jed: (fab is short for find and bind: first arg is the path, second (optional) arg is the handler. pretty easy once you get it.)
[21:26] konobi: has anyone seen anyone doing mdns with node?
[21:33] bronson has joined the channel
[21:33] r11t has joined the channel
[21:35] jfd has joined the channel
[21:39] felixge has joined the channel
[21:43] mikeal has joined the channel
[21:52] ithinkihaveacat_ has joined the channel
[21:56] sztanpet has joined the channel
[21:57] technoweenie: hey does anyone have experience hitting streaming apis w/ node.js
[21:58] technoweenie: i think twitters streaming api is dying, but node.js isnt emitting a proper event?
[21:58] isaacs: technoweenie: not sure eactly what you mean...
[21:58] isaacs: oh, like xmpp?
[21:58] technoweenie: streaming http api
[21:58] technoweenie: sorry, forgot the protocol, small detail!
[21:59] isaacs: hehe
[21:59] isaacs: sure, you can just use the http.createClient, i believe.
[21:59] isaacs: should Just Work.
[21:59] technoweenie: http://github.com/technoweenie/twitter-node/blob/master/lib/index.js#L41-58
[21:59] technoweenie: well, its dying
[21:59] technoweenie: i just want to fail gracefully
[21:59] jfd has joined the channel
[22:00] isaacs: oic
[22:00] isaacs: how's it failing?
[22:00] technoweenie: i dont know, its just not receiving events
[22:01] isaacs: that's odd
[22:01] isaacs: can you hit the api with curl or something and see what it shows you?
[22:01] technoweenie: hmm i think its my code actually
[22:01] technoweenie: fuck
[22:01] technoweenie: you should see my screen
[22:02] technoweenie: scrolling tweets about the ipad
[22:02] technoweenie: my json parsing must be breaking
[22:02] isaacs: ipad? what's that?
[22:02] isaacs: ACTION is a troll, sorry, i'll stop.
[22:03] technoweenie: oh i think i'm getting multiple tweets in each response chunk
[22:03] technoweenie: man how do i parse this? do i count brackets to make sure i have isolated json nodes
[22:04] jfd has joined the channel
[22:04] deanlandolt: technoweenie: heh...i was just thinking about a streaming json parser
[22:04] technoweenie: yajl
[22:04] technoweenie: if you can do node bindings for that, i would be your bff
[22:04] deanlandolt: oooh
[22:04] technoweenie: BUT how does it stream? will it handle multiple documents
[22:05] technoweenie: I think what happens is i get a chunk like {"text": "a and b"}
[22:05] technoweenie: so i buffer pieces that arent valid json
[22:05] technoweenie: but then sometimes i get a chunk thats a part of two tweets
[22:05] technoweenie: so i never really have a single valid tweet
[22:06] technoweenie: deanlandolt: do you think you could do a node.js binding? i dont know shit about c/c++
[22:06] deanlandolt: technoweenie: i don't either :-/
[22:06] deanlandolt: but there are python and ruby bindings, interestingly
[22:07] orlandov: why's it need to be in c or c++?
[22:07] deanlandolt: perhaps a stdio with a simple jsonline protocol (a la couch) could work
[22:07] technoweenie: well yajl is c i guess
[22:07] technoweenie: so bindings to that would rock
[22:07] thijs_ has joined the channel
[22:08] technoweenie: it does events, it'd be perfect for node.js
[22:08] thijs_: question, how do I connect to a database with node.js? are there any working examples? I can't seem to find one on the interwebz that's actually giving me more info than: add dbslayer and it works
[22:09] technoweenie: thijs_: there's an experimental postgres driver for node.js
[22:09] technoweenie: but the mysql c bindings arent async so its not a good fit for node
[22:09] thijs_: technoweenie, i see...
[22:12] orlandov: thijs_: what kind of db do you need?
[22:12] orlandov: i think there are a few nosql db's with node drivers
[22:12] technoweenie: mongodb has one
[22:12] jfd has joined the channel
[22:12] technoweenie: not sure if its any good
[22:12] orlandov: yeah it's still pretty young
[22:12] thijs_: orlandov, i wanted to try to get node working with mysql
[22:13] rolfb has joined the channel
[22:13] CIA-75: node: 03Standa Opichal 07master * r5a70224 10/ (tools/osx-dist.sh tools/osx-pkg-dmg-create.sh): (log message trimmed)
[22:13] CIA-75: node: Adding OS X .dmg build scripts.
[22:13] CIA-75: node: Simply place this into the root of your nodejs git working copy and
[22:13] CIA-75: node: run ./tools/osx-dist.sh. It will create an dist-osx folder which will
[22:13] CIA-75: node: comprise of the resulting .dmg file (install path is
[22:13] CIA-75: node: /usr/local/nodejs with symlinks added to /usr/local/bin) along with
[22:13] CIA-75: node: other files used during its construction.
[22:14] orlandov: thijs_: you've seen this? http://github.com/Guille/node.dbslayer.js/
[22:15] thijs_: orlandov, yeah, i've seen it, was about to try it, but i figured i might just try my luck here before i end up installing more stuff
[22:17] ryah_away: isaacs: you should benchmark iterating over an array with for(i =0; i < a.length;i++) and forEach
[22:17] isaacs: ryah_away: kk.
[22:17] ryah: i wonderif there is some difference
[22:18] isaacs: it's an interesting question.
[22:18] konobi: thijs_: there's postgres drivers for node
[22:18] konobi: async and everything
[22:18] isaacs: i'm guessing it may vary slightly depending ont eh array size.
[22:18] thijs_: konobi, thanks
[22:18] deanlandolt: hmm...one problem with forEach is you have to throw to break out of it...
[22:19] ryah: isaacs: yeah - try short arrays
[22:19] deanlandolt: but at least in persvr i know it's faster
[22:19] ryah: 10 items
[22:19] isaacs: yep.
[22:19] deanlandolt: also, to be fair to performance, make sure you assign the length upfront so it doesn't have to be looked up every time
[22:19] deanlandolt: for(var i=0, l = a.length; i < l; i++)
[22:20] ryah: i suspect that didn't make a difference
[22:24] felixge: does anybody know if its a good idea to use delete a[1] on an array?
[22:25] isaacs: deanlandolt: testing all thre
[22:28] hassox has joined the channel
[22:29] hassox: ryah: hey man
[22:29] isaacs: ryah: http://gist.github.com/288214
[22:30] isaacs: so, lengthCached is doing the for (var i = 0, l = list.length; i < l;i ++)
[22:30] isaacs: that's the fastest.
[22:30] hassox: hey isaacs
[22:30] hassox: what are thyese?
[22:30] isaacs: but at 2k ops per sec vs 4k ops per sec, it doesn't make much of a difference, really
[22:30] isaacs: either way, it's a puny diff.
[22:30] orlandov: huh wow
[22:31] felixge: isaacs: interesting to see forEach 2x slower than the rest
[22:31] felixge: isaacs: could you try filter() real quick?
[22:31] Booster has joined the channel
[22:31] isaacs: sure
[22:31] felixge: should do the same as forEach if you pass no return values
[22:31] orlandov: i wonder if the fn call is killing the performance
[22:31] isaacs: you know, i'm just using this: http://github.com/isaacs/node-bench
[22:31] isaacs: you can all do this, too :)
[22:31] BBBB has joined the channel
[22:31] ryah: isaacs: thanks
[22:32] felixge: isaacs: have not seen it
[22:32] felixge: but will check it out now
[22:32] felixge: working on dirty
[22:32] felixge: :)
[22:32] dekz has joined the channel
[22:32] ryah: so - in node we use loops :)
[22:33] hassox: isaacs: er what are we benchmarking?
[22:33] felixge: isaacs: why is this a binary and not just a module?
[22:33] ryah: at least in code that gets executed often - e.g. iterating over http headers
[22:33] felixge: also, 2k/4k ops/sec seems *very* slow for iterating over an array, no?
[22:34] isaacs: hassox: added the bench script: http://gist.github.com/288214
[22:34] isaacs: felixge: because the mac is an idiot.
[22:34] isaacs: felixge: and doesn't support shebang chaining
[22:34] felixge: oh
[22:34] felixge: ok :|
[22:34] isaacs: ryah: ok, i'm cool with that.
[22:35] felixge: isaacs: I think your benchmark is somewhat flawed
[22:35] isaacs: felixge: oh?
[22:35] felixge: appending a string could have side effects on the results that are hard to predict
[22:35] felixge: I'd just increment a second integer instead
[22:36] felixge: also, the list you are using is very short
[22:36] isaacs: felixge: but it's a realistic proxy for "do something with the string"
[22:36] isaacs: and the list length is representative of http headers.
[22:36] felixge: oh wait, the string is relevant in this bnechmark?
[22:36] isaacs: it's unlikely that you'll have more than 2 in most cases.
[22:36] felixge: I thought this was just about array iteration
[22:36] isaacs: felixge: it's about array iteration in the case of http headers.
[22:36] felixge: oh ok
[22:36] ryah: isaacs: how about counting te length of all the strings in the array
[22:37] isaacs: ryah: so, i'll update the ejsgi spec to say that the headers must be an object containing either strings or arrays of strings.
[22:37] isaacs: ryah: sure, i'll test that.
[22:37] ryah: (instead of concating them)
[22:38] felixge: isaacs: what are your "scores" representing?
[22:38] ryah: felixge: ops/sec
[22:39] felixge: ops as in calling the function once?
[22:39] ryah: yeah
[22:39] felixge: that seems really slow
[22:39] isaacs: ryah: so, the scores are higher, but the ranking is the same: http://gist.github.com/288214
[22:40] felixge: but I get the same result s locally
[22:40] isaacs: felixge: it's not really intended to be a precise measurement so much as a comparison.
[22:40] isaacs: it's more a "stand back to back and lets see who's taller" rather than "step on the scale and let's get your height" kinda deal.
[22:41] felixge: isaacs: well, its just off by 2-3 orders of magnitude of what I'd expect
[22:41] isaacs: haha
[22:41] felixge: so that makes me wonder :)
[22:41] isaacs: there's a timer and some checking in there, too
[22:41] ryah: how fast does ruby do it? :)
[22:41] deanlandolt: felixge: it could be that it's a tiny tiny list and it's not counting the overhead for allocating the fn
[22:41] felixge: maybe
[22:41] felixge: but I doubt it
[22:42] isaacs: again, it's not a precise measurement, it's strictly intended to only be a comparison to see which one is faster relative to the other.
[22:42] felixge: either that or I completely screwed up my benchmarks for dirty
[22:42] felixge: I do 600k / sec of way more complicated operations
[22:42] felixge: involving several function calls
[22:42] isaacs: felixge: could be you have a better machine, or that you have less other crap going on.
[22:42] felixge: isaacs: well either this number is ops/sec or its some score that has nothing todo with it
[22:42] ryah: there is probably overhead in the benching program
[22:42] felixge: isaacs: no, I get the same results as you with your node-bench sample
[22:43] isaacs: felixge: if you find a bug in node-bench, i'd love a patch!
[22:43] isaacs: ;)
[22:43] felixge: isaacs: I'll take a look :)
[22:43] ryah: but generlly i think function calls arnt so fast
[22:43] felixge: ACTION hopes he didn't screw up his benchmarks
[22:43] dekz_ has joined the channel
[22:44] isaacs: felixge: considering that see 12k requests per second for node http servers, yeah, 2k/sec for iterating through a list is puny.
[22:44] isaacs: maybe it's ops/ms...
[22:44] felixge: isaacs: that would make more sense
[22:44] isaacs: eh. whatever. the scores are in "points"
[22:44] isaacs: scoring higher means you win.
[22:44] isaacs: it's like pac man.
[22:44] felixge: in fact, I'd say its ms
[22:44] felixge: :)
[22:45] isaacs: oh, haha, it IS ms
[22:45] isaacs: because non-async functions get called 1000 times per "op", i think
[22:45] felixge: good :)
[22:45] ryah: :)
[22:45] felixge: I was afraid v8 was 1000x slower than I thought :)
[22:46] felixge: good to know, will play with node-bench a bit now
[22:46] felixge: to test some assumptions on how I structure my data in dirty :)
[22:46] isaacs: oh, actually, no... i factor that back out
[22:46] isaacs: the issue is probably that there's a process.nextTick every 1000 ops
[22:47] isaacs: so that i can check the timer and see if it's dinged yet.
[22:47] felixge: btw. I do think v8 got slower after the last upgrade, at least my dirty benchmarks for iteration have slowed down a lot
[22:48] felixge: which would suck
[22:48] RayMorgan: if it has, I am sure it is a bug :)
[22:48] felixge: I should probably investigate and maybe report it
[22:48] felixge: :)
[22:48] jcrosby has joined the channel
[22:48] mikeal: is there a specific reason inherits() is in sys?
[22:48] mikeal: it feels just a little out of place
[22:49] isaacs: ryah: so, yeah, we should use for, and cache the length, it looks like.
[22:49] ryah: mikeal: not really
[22:49] ryah: just randomly put it there
[22:49] mikeal: that's what i figured :)
[22:50] jed has joined the channel
[22:51] isaacs has joined the channel
[22:52] jed: isaacs: you should add the while ( i-- ) { ... } iteration to your tests.
[22:53] jed: i seem to remember that being the fastest in some tests i saw a while ago.
[23:03] ryah: i wish v8 would do a release
[23:07] RayMorgan: yeah, seems like a while since their last release
[23:07] ryah: hey
[23:07] RayMorgan: I read that they were working on a new compiler.. so maybe that is taking up their time?
[23:08] ryah: (oops wrong window)
[23:11] hassox: ryah: is there a streamer in node core?
[23:12] isaacs: jed: will do
[23:12] jed: just did.
[23:12] ryah: hassox: streamer?
[23:12] isaacs: jed: how's it measure up?
[23:12] jed: lengthCached is 2.88% faster.
[23:13] isaacs: nice
[23:13] hassox: ryah: something to Stream with...
[23:13] ryah: hassox: socket?
[23:13] hassox: ryah: nah... obviously not then ;)
[23:13] felixge: hassox: do you mean the new net2 stuff?
[23:14] technoweenie: hassox: http streaming?
[23:14] hassox: felixge: nah the stuff like isaacs stream lib
[23:14] hassox: technoweenie: streaming from a stream object (could be used as a data pump or for http)
[23:14] technoweenie: oh reading/writing file streams
[23:14] hassox: not file streams
[23:14] felixge: hassox: I think that is part of what ryan is working on for net2
[23:14] hassox: data stream
[23:15] hassox: felixge: oh right
[23:15] hassox: technoweenie: could be a file stream...
[23:15] dekz has joined the channel
[23:15] hassox: technoweenie: checkout http://github.com/isaacs/node-stream
[23:15] rtomayko has joined the channel
[23:16] dekz_ has joined the channel
[23:17] jed: isaacs: hah, found a new winner by 3.88%
[23:17] hassox: isaacs: there's a bug in that btw
[23:17] hassox: I'll send you a pull request later
[23:17] paulca has joined the channel
[23:17] jed: isaacs: for (var len = 0, i = 0, l = list.length; i < l; ) len += list[ i++ ].length;
[23:18] isaacs: hassox: sure.
[23:18] isaacs: patches welcome, as always.
[23:18] isaacs: what's the jist of the bug? i'm curious.
[23:19] hassox: it can emit eof more than once
[23:19] hassox: if you do stream.write("foo") <-- which drains
[23:19] hassox: then stream.close()
[23:19] hassox: the eof can be called twice
[23:20] hassox: ior emitted
[23:20] orlandov: jed: where is len used in that snippet?
[23:20] hassox: isaacs: fix: http://gist.github.com/288262
[23:20] isaacs: hassox: hm, it should only emit eof if buffer.closed
[23:21] hassox: isaacs: write calls a flow, which in the next tick drains (and because it's closed does eof)
[23:21] isaacs: hassox: please use {} around if blocks if it's more than one line.
[23:21] hassox: then close() does a flow which doesn't check to see if it's been emitted...
[23:21] jed: orlandov: it's only used as the sum (as with all of the other functions in isaac's gist).
[23:21] hassox: where?
[23:22] isaacs: line 41
[23:22] hassox: oh i see it
[23:22] hassox: yeah
[23:22] hassox: soz
[23:22] orlandov: jed: you mean that's the "work" the loop is doing?
[23:22] orlandov: rather than just spinning
[23:22] isaacs: um, write checks to see if the buffer is 0, and if it's 0 emits train, and if it's also closed, emits eof, and then returns, so it never calls flow()
[23:22] jed: orlandov: correct: http://gist.github.com/288214
[23:23] orlandov: ah gotcha
[23:23] technoweenie: can you do array accessors in js? var a, b = [1,2]
[23:24] isaacs: technoweenie: only in mozilla engines.
[23:24] deanlandolt: technoweenie: they call it destructering..and yeah, what isaacs said
[23:24] technoweenie: blah ok thanks :)
[23:24] deanlandolt: anyone know if that's on the docket for harmony?
[23:25] deanlandolt: it's pretty sexy -- especially object destructuring for explicit dsls
[23:26] eikke has joined the channel
[23:27] stevestmartin has joined the channel
[23:28] hassox: isaacs: it emits twice...
[23:28] jacobolu_ has joined the channel
[23:28] hassox: stream.write("foo"); stream.close()
[23:28] isaacs: ACTION testing
[23:29] hassox: flow is called for each one, but deferred to the next tick
[23:29] eddanger has joined the channel
[23:30] eddanger has left the channel
[23:31] isaacs: hassox: mmm.... nope. try the test/test/js
[23:31] isaacs: test/test.js
[23:31] isaacs: i just added close() to it, and i'm outputting the EOFs
[23:32] isaacs: flow only does something if it's not already flowing
[23:34] hassox: isaacs: I'll look at it a bit later dude
[23:35] hassox: ACTION is at work atm
[23:35] isaacs: ACTION is also at work atm
[23:35] isaacs: hehe
[23:35] hassox: ;)
[23:37] joshbuddy has joined the channel
[23:43] technoweenie: oh sweet i got my twitter streamer working
[23:44] hassox: technoweenie: :D
[23:44] hassox: nice one
[23:44] technoweenie: i had this bug where some response bodies would return parts of 2 tweets
[23:44] technoweenie: so the json was invalid
[23:44] technoweenie: i figured out that you just split on newlines
[23:44] hassox: technoweenie: are you using the streaming api?
[23:45] technoweenie: yea
[23:45] hassox: I found that each chunk could be multiple tweets and/or the last tweet could be partial
[23:45] hassox: they're split on \r\n
[23:46] technoweenie: yea
[23:46] technoweenie: the code for it is a little weird
[23:46] technoweenie: but whatever, it works
[23:48] hassox: nice one m,an
[23:48] hassox: :)
[23:49] technoweenie: i have a video of it, hold on
[23:49] technoweenie: http://dl.dropbox.com/u/3561619/IMG_0573.MOV
[23:49] technoweenie: searching for 'apple' and 'ipad' :)
[23:50] hassox: nice :D