[00:08] bryanl has joined the channel [00:11] binary42 has joined the channel [00:23] ryan_a has joined the channel [00:24] ryan_a has left the channel [00:25] soveran has joined the channel [00:32] eddanger has joined the channel [01:08] sztanphet has joined the channel [01:12] rektide has joined the channel [01:12] [k2] has joined the channel [01:12] Atmoz has joined the channel [01:13] un0mi has joined the channel [01:15] intellectronica has joined the channel [01:16] micheil has joined the channel [01:19] Yuffster_ has joined the channel [01:19] olivvv has joined the channel [01:19] alex-desktop has joined the channel [01:19] Yuffster has joined the channel [01:19] aurynn has joined the channel [01:19] zimbatm has joined the channel [01:19] keeto has joined the channel [01:19] r11t has joined the channel [01:19] stephenlb has joined the channel [01:19] isaacs has joined the channel [01:19] FoxFurry has joined the channel [01:19] brandon_beacher has joined the channel [01:20] Vito` has joined the channel [01:22] alexiskander has joined the channel [01:27] sudoer has joined the channel [01:39] jamiew_ has joined the channel [01:40] ericflo has joined the channel [01:48] hassox: hullo noders [01:55] jamiew has left the channel [02:10] robrighter has joined the channel [02:20] cloudhead has joined the channel [02:20] binary42 has joined the channel [02:34] bryanl has joined the channel [03:00] grantmic_ has joined the channel [03:08] jed has joined the channel [03:36] eddanger has joined the channel [03:43] inimino: ACTION just got email from an old client out of the blue to do some node work for them o_O [03:44] inimino: I think this node thing might be catching on [03:45] hassox: hehe [03:47] mahemoff_ has joined the channel [03:53] kriszyp_ has joined the channel [04:02] hassox: lads what's the half completed package manager called? [04:08] jspiros has joined the channel [04:09] bengl: hassox: kiwi? [04:09] hassox: aussie [04:09] hassox: oh [04:09] hassox: haha [04:09] hassox: thx [04:20] ryah: hassox: hey [04:20] brosner has joined the channel [04:20] hassox: gday mate [04:21] hassox: how are you [04:21] ryah: good [04:21] hassox: :) [04:21] hassox: quick one if you've got a couple of minutes [04:21] brosner has left the channel [04:21] hassox: I'm trying to cat a file and output it as part of some testing [04:21] hassox: in a web service [04:22] hassox: but when I dial up the concurrency to 3 or above, the file is never cat'd [04:22] hassox: no events are raised... it freezes [04:22] ryah: hm [04:23] hassox: I added a comment to an issue the other day but I'm not sure if it's the same thing [04:23] ryah: hassox: what if you 'git revert 0d7e88a4298740751bf0e8dabf9015baf88f455a', recompile and try? [04:23] hassox: 1 sec [04:24] hassox: while it's compiling http://github.com/ry/node/issues#issue/38 [04:30] hassox: ryah: same thing [04:30] ryah: okay [04:30] ryah: i'll look at it soon :/ (pressed for time these days) [04:32] hassox: undestood [04:32] hassox: wish I new more to be able to help out... [04:32] hassox: js is hard for me.. I know about 0 c [04:32] orlandov: hassox: reporting broken things is a good way of contributing [04:33] orlandov: most people don't even do that [04:33] hassox: yeah I know [04:33] hassox: but directly hacking is much more rewarding ;) [04:33] orlandov: imo start hacking on the core stuff [04:33] orlandov: if you know c, it shouldn't be too bad [04:33] orlandov: even for c++ ;) [04:33] hassox: oh [04:33] hassox: hehe [04:33] hassox: there you go [04:33] hassox: I can't even tell the diff between c++ and c [04:34] ryah: yes, i should be able to fix is relatively easy if i can reproduce it from that script in the bug report [04:34] hassox: ryah: I can put a more detailed script together if that one doesn't do it [04:34] ryah: and having multiple people complain does help motivate me :) [04:34] hassox: hrm [04:34] orlandov: so long as you don't burn out ryah [04:34] ryah: hassox: you could put together a test/mjsunit script [04:34] hassox: ACTION goes to motivate my friends [04:34] hassox: ryah: that I can do [04:36] hassox: lads, if I want to check a number of directories for the presence of a file [04:37] hassox: what's a good way? [04:40] ryah: posix.stat [04:41] o7: Hrm. What’s the canonical way to repeat a string x times? [04:41] o7: i.e. as (str * n) would do in Ruby [04:42] o7: inimino: ^^ [04:44] orlandov: http://stackoverflow.com/questions/202605/repeat-string-javascript [04:45] inimino: o7: using a loop [04:45] orlandov: tl;dr there's no pretty solution, i think [04:45] inimino: o7: there's a cute idiom involving Array if you're into cuteness [04:46] orlandov: ooh [04:46] orlandov: i like that array one [04:47] inimino: that's the cute one, yes [04:48] orlandov: what would inimino do? [04:48] orlandov: using a for loop seems kinda ick [04:48] gwoo has joined the channel [04:49] inimino: I'd probably write a function repeat(str,n) [04:50] orlandov: well, yeah, i mean i wouldn't inline that whole thing into an expression [04:50] orlandov: but how would you implement it [04:54] hassox: ryah: what do you mean posix.stat? [04:55] ryah: hassox: to see if a file exists [04:56] inimino: orlandov: I'd probably just write... [04:56] hassox: ryah: I'm wondering how to check multiple directories for the presence of a file [04:56] hassox: do you do it with promisies? [04:57] inimino: orlandov: actually I'd probably just do the Array thing [04:59] inimino: http://www.infoq.com/presentations/Systems-that-Never-Stop-Joe-Armstrong [05:00] inimino: excellent talk [05:06] inimino: orlandov: the reason is that it might be optimized in the interpreter, more so than repeated string += [05:06] soveran has joined the channel [05:07] orlandov: inimino: yeah i figure, doing it in the string handling builtin as much as possible is best [05:14] martint-t has joined the channel [05:18] scudco has joined the channel [05:20] r11t has joined the channel [05:23] CIA-56: node: 03isaacs 07master * r7342fec 10/ src/node.js : [05:23] CIA-56: node: Improve path module slightly: [05:23] CIA-56: node: 1. Provide a switch to tell it to not remove empty path parts when [05:23] CIA-56: node: normalizing. [05:23] CIA-56: node: 2. Correct the handling of some edge cases when you have lots of dots and [05:23] CIA-56: node: empty bits, such as paths like "././/./..//." and so on. - http://bit.ly/83XQFd [05:23] CIA-56: node: 03isaacs 07master * rd6fe7fb 10/ doc/api.txt : Documentation for path module - http://bit.ly/6NnPkP [05:23] CIA-56: node: 03isaacs 07master * r7ff04c1 10/ (5 files in 3 dirs): [05:23] CIA-56: node: Add URL and QueryString modules, and tests for each. [05:23] CIA-56: node: Also, make a slight change from original on url-module to put the [05:23] CIA-56: node: spacePattern into the function. On closer inspection, it turns out that the [05:23] CIA-56: node: nonlocal-var cost is higher than the compiling-a-regexp cost. [05:23] CIA-56: node: Also, documentation. - http://bit.ly/7hrJ4r [05:23] CIA-56: node: 03isaacs 07master * r2b3d9e4 10/ (11 files in 3 dirs): (log message trimmed) [05:23] CIA-56: node: Use "url" module instead of "uri" module in http.js. [05:23] CIA-56: node: Deprecate the URI module and remove tests for it. [05:23] CIA-56: node: - Rename "uri" to "url". [05:23] CIA-56: node: - Use the "url" module instead of the "uri" module. [05:24] CIA-56: node: - Remove the url parsing from http.js [05:24] CIA-56: node: - Update http.cat with the changed field names. [05:27] cloudhead has joined the channel [05:40] mikekelly has joined the channel [05:42] hassox: ryah: inimino lads is there a way to find out the path of the file that we're currently in? [05:42] hassox: as an expanded path? [05:43] ryah: hassox: require("path").join(__filename, "..") ? [05:43] ryah: something like that [05:43] hassox: oh sweet :D [05:43] hassox: is htere a list of __foo style constants anywhere mate? [05:43] ryah: in the doc [05:44] ryah: i guess just __filename [05:44] hassox: http://nodejs.org/api.html [05:44] hassox: ? [05:44] ryah: yeah [05:44] hassox: I see it thanx [05:44] hassox: :) [05:46] hassox: champ [05:52] scudco has joined the channel [05:57] ryah: hassox: any luck on that test? [05:57] hassox: ryah: sorry mate [05:58] hassox: I'm at work atm [05:58] hassox: I was going to get onto it after dinner [05:58] hassox: I didn't realise you were waiting [05:58] ryah: i wasn't [05:59] hassox: cool [05:59] hassox: :) [06:12] CIA-56: node: 03visionmedia 07master * ra650138 10/ (bin/node-repl lib/repl.js): Moved help msg to node-repl - http://bit.ly/6nBvF8 [06:21] CIA-56: node: 03Charles Lehner 07master * rcaf22c8 10/ src/node.js : Fixed clearTimeout to check if timer is a Timer - http://bit.ly/8nl8Bd [06:27] tiglionabbit has joined the channel [06:27] tiglionabbit: hi [06:28] ryah: tiglionabbit: hi [06:29] tiglionabbit: nodejs is pretty awesome. I'm ready to start making stuff with it, but right now I'm just trying to decide which libraries would work best with it, since I haven't done server side javascript before [06:29] tiglionabbit: good thing this page is here http://wiki.github.com/ry/node [06:32] tiglionabbit: I'll probably be using mongodb for my database. Templating is still up in the air - I'd like something I can use on both the server and client, and can do inheritance/includes decently. And, do you find these 'web frameworks' things useful? [06:33] tiglionabbit: wuh oh, this doesn't look like it's very near done yet... http://github.com/erh/mongo-v8-driver [06:57] tiglionabbit: huh, how do you get node.js to serve static files? [07:01] ryah: very carefully [07:01] ryah: :) [07:01] ryah: i think some of these frameworks has some examples [07:05] tiglionabbit: is it recommended, or do people generally run another server for that stuff? [07:05] tiglionabbit: heh, could always use s3 if it came to that [07:07] ryah: shrug, depends on what you're doing of course [07:07] ryah: useful for debugging [07:07] ryah: probably best to use nginx to serve static files in production [07:26] felixge has joined the channel [07:28] ryah: felixge: i might have solved a problem of yourse [07:28] ryah: an eio bug [07:29] mikeal has joined the channel [07:29] ryah: psh [07:30] ryah: hassox: fixed your bug [07:32] sudoer has joined the channel [07:34] CIA-56: node: 03Ryan Dahl 07master * raf6c177 10/ (5 files): Upgrade libeio to latest CVS - http://bit.ly/8DNtHM [07:34] CIA-56: node: 03Ryan Dahl 07master * r933a37c 10/ (8 files): Upgrade libev to 3.9 - http://bit.ly/7KUzX9 [07:34] CIA-56: node: 03Ryan Dahl 07master * r04dd2d5 10/ (2 files in 2 dirs): [07:34] CIA-56: node: libeio bugfix: want_poll should be called if breaking on maxreq [07:34] CIA-56: node: Reported by shansen and hassox [07:34] CIA-56: node: http://github.com/ry/node/issues#issue/38 [07:34] CIA-56: node: Will send upstream. - http://bit.ly/6JLmrL [08:04] elliottcable: ryah: should I pull request a little change, or what? [08:04] ryah: elliottcable: link me [08:04] elliottcable: ryah: it applies on top of your master as of right now: http://github.com/elliottcable/node/commit/984299f733aa838c31a5070af28a32f37d8080ca [08:05] elliottcable: ryah: the point is so I can replace sys.p with cloudhead’s eyes.js when using the repl [08:05] ryah: elliottcable: add a comment explaining it, otherwise lgtm [08:06] elliottcable: ryah: In the source? [08:06] ryah: yeah [08:06] elliottcable: ryah: done, don’t pull, am going to append [08:11] elliottcable: ryah: kfx’d http://github.com/elliottcable/node/commit/1512ae2f64977ead13f3671a8a517eadc6465226 [08:14] CIA-56: node: 03elliottcable 07master * r52f088b 10/ lib/repl.js : Providing the option for a repl-printer other than sys.p - http://bit.ly/5Z4kck [08:15] elliottcable: woowoo [08:20] johan-s has joined the channel [08:22] _ry has joined the channel [08:25] DamZ has joined the channel [08:28] tiglionabbit: which of these frameworks handles static files? [08:30] _ry: tiglionabbit: here is a simple example: http://github.com/ry/node_chat/blob/master/fu.js#L61-99 [08:39] micheil has joined the channel [08:43] kriskowal has joined the channel [08:59] spoob has joined the channel [09:40] elliottcable: arkgh [09:40] elliottcable: WARNING: promise.wait() is being called too often. [09:44] halorgium: elliottcable: "Use promise.wait() sparingly" ;) [09:44] elliottcable: yeah [09:44] elliottcable: was an infinite loop [09:44] halorgium: lolz [09:45] halorgium: elliottcable: been specing async rack [09:45] elliottcable: wat [09:45] halorgium: http://github.com/halorgium/rack2 [09:47] elliottcable: wat [09:47] halorgium: code discussion with raggi and tmm1 [09:48] elliottcable: ACTION hasn’t touched anything in Ruby for aaaages now [09:48] elliottcable: so forgive me if I’m confused [09:48] teemow has joined the channel [09:48] halorgium: elliottcable: haha, true async rack [09:49] halorgium: not the env["async.callback"] and -1 status code hax in thin [09:49] elliottcable: I’m not familiar with either [09:49] elliottcable: oh wait it’s halorgium [09:49] elliottcable: I confused you with hassox [09:49] halorgium: haha [09:49] hassox: hey lad [09:49] hassox: s [09:50] hassox: halorgium: I wanted to ask you about that [09:50] elliottcable: he’s been in here too, and I knew him from the Ruby community too [09:50] halorgium: yer, hassox and i go way back ;) [09:50] elliottcable: lol [09:50] elliottcable: orly [09:50] hassox: halorgium: sshhhh [09:50] elliottcable: you should both /join ##Paws then! hah! [09:50] elliottcable: wait. [09:50] elliottcable: that logic had a hole. [09:50] elliottcable: I’m just not sure what it is. [09:50] hassox: halorgium: about rack2 [09:51] hassox: I thought about putting events and async into ruby [09:51] hassox: but at it's lower levels... [09:51] hassox: file access, url access etc [09:51] hassox: almost all libs are written for sync code [09:51] elliottcable: yep [09:51] elliottcable: hence hte problem [09:51] elliottcable: and the one that Node.js solves [09:51] hassox: so the benefit of implementing async in ruby is kinda silly [09:51] elliottcable: by forcing a new ecology on you [09:51] hassox: isn't it? [09:51] elliottcable: sure, there’s no supporting ecology as with Ruby, but there’s also no sync ecology holding you *back* [09:51] hassox: elliottcable: that's the conclusion I came to also [09:51] elliottcable: also the same conclusion Paws comes to [09:52] halorgium: hassox: yer, you are right [09:52] elliottcable: new language, new ecology, all 100% async [09:52] halorgium: but it is possible to not depend on sync libs [09:52] halorgium: or at least minimize their use [09:52] hassox: sure [09:52] hassox: but you'd have to build up all those libs from scratch [09:52] hassox: so we're in a very simliar situation [09:52] elliottcable: that’s true anywhere [09:52] elliottcable: I think the problem is that having that sync ecology holds you back intellectually [09:52] hassox: only, in node, everything is evented at it's core [09:53] elliottcable: forces you to try to think sync before you ever think async [09:53] hassox: elliottcable: there's that [09:53] halorgium: of course, but abandoning ruby because of that reason is not a good one IMO [09:53] elliottcable: Oh, ’snot why I left [09:53] hassox: I don't want to abandon ruby [09:53] elliottcable: hassox: I think he was talking about me [09:53] hassox: I still think ruby has a lot to offer [09:53] elliottcable: hassox: I could be Off™ [09:53] halorgium: ACTION was exaggerating [09:53] hassox: bbiab [09:53] elliottcable: o7 [09:54] halorgium: i've been trying to make it apparent that async is not that more complex than sync [09:54] hassox: be back in a bit [09:54] hassox: halorgium: that's tru [09:54] hassox: halorgium: but complex libs are a.ready coded as sync [09:55] elliottcable: yeah [09:55] halorgium: and people definitely will do the wrong thing if they are given the opportunity [09:55] elliottcable: the languages also make it difficult [09:55] halorgium: elliottcable: disagree there [09:55] elliottcable: that’s why I went with making a new one, I wanted one where ‘being async’ wasn’t going *against* the thread [09:56] hassox: halorgium: agreed... it's simple to write sync code in js [09:56] elliottcable: halorgium: you don’t think `foo(function(result){ … use result … })` is more difficult than it has to be? [09:56] halorgium: converting sync libs to async is not hard given they are not insane [09:56] hassox: kk [09:56] hassox: bbiab [09:56] hassox: this is an interesting topic [09:56] halorgium: elliottcable: oh, it is more difficult [09:56] hassox: hope you lads are still here ;) [09:56] halorgium: but i don't think it is hard [09:56] elliottcable: o_O [09:56] elliottcable: so what do you disagree with? [09:56] elliottcable: I didn’t say it was hard, I said it was more difficult, exactly what you just said [09:56] halorgium: hmm, ok [09:57] inimino: it's not hard, just ugly [09:57] inimino: JavaScript lambda syntax is ugly [09:57] halorgium: i was talking absolutely, you were talking relatively [09:57] elliottcable: ah, but the same is true of Ruby [09:57] elliottcable: they all sideline CPS, and the vast majority of their operations rely on the ages-old ‘return to caller’ concept [09:57] elliottcable: which is just too inherently synch to work around [09:58] inimino: halorgium: your API ideas look good [09:58] inimino: (from a quick look) [09:58] halorgium: inimino: it is basically node converted to ruby ;) [09:58] halorgium: obviously no file stuff though :( [09:58] halorgium: or eio [09:59] spoob: I'm ex-Ruby too, and I find that Javascript is about as nice to use once you get past the problems [09:59] elliottcable: I’m not ex-Ruby because JS is better [09:59] elliottcable: mind you, JS is way better than anybody gives it credit for, if you use it correctly [09:59] halorgium: i really hope JSGI doesn't stick to sync [10:00] halorgium: anything is better when you use it better than something else that you use terribly ;P [10:00] elliottcable: yeah, *that* made a lot of sense d-: [10:01] halorgium: elliottcable: haha, it was designed to explode your brain! [10:01] elliottcable: consider it exploded. [10:01] elliottcable: anyway. [10:01] spoob: I'm trying to remember where I saw Javascript implementing the Ruby "yield" command [10:01] elliottcable: I have a fuckton of interpreter to write. [10:01] elliottcable: I need a reference impl of Paws! [10:01] elliottcable: so I can fricking explain what I’ve been saying all along! >,< [10:03] halorgium: elliottcable: i hope you've removed the return keyword from your lang [10:03] elliottcable: halorgium: what? [10:04] elliottcable: halorgium: there’s no concept of returning; the path of execution always, always moves forwards [10:04] halorgium: exactly [10:04] halorgium: so no need for "return" [10:04] elliottcable: yep [10:04] elliottcable: well there’s no keywords, so I can’t exactly *remove* the keyword [10:04] halorgium: perhaps i should have said "haven't implemented" [10:04] elliottcable: hahaha yeah [10:05] halorgium: for elliottcable so created the world .... [10:05] elliottcable: (-:< [10:05] spoob: while it's cool and fun to do your own languages, are you hoping to have users and developers? [10:05] elliottcable: spoob: It’d be cool. I’m not creating it for everyone else, though, I’m creating it for me. [10:06] elliottcable: spoob: if anybody else uses it, they’ll be people who think like me. If there’s no people who think like me (unlikely, but possible), then there’ll be no users but me. Heh! [10:06] halorgium: elliottcable: do you have a lang spec? [10:06] spoob: What significant difference does your language have other than being "node in Ruby"? [10:07] halorgium: spoob: talking to me? [10:07] elliottcable: halorgium: I’m not a language designer or anything; the only way I’ve been able to get this language out of my head is by implementing it [10:07] spoob: no, elliotcable [10:07] elliottcable: spoob: this is neither in Ruby, nor node [10:07] elliottcable: spoob: you confused me with halorgium d-: [10:07] halorgium: spoob: i was the one who said "node in ruby" [10:07] spoob: ah [10:07] elliottcable: let’s take this to ##Paws, halorgium, spoob, and I think hassox is already there [10:07] halorgium: and i was talking about rack2 being node/http in ruby [10:08] spoob: I'm overdosed on languages, which was the only thing I was going to say... :) [10:09] halorgium: spoob: yer, sometimes it is nice to go higher level ;) [10:09] spoob: that, and "javascript has its horrible bits but it's good enough for now" [10:09] spoob: my other language is GLSL in WebGL :) [10:10] spoob: (and Objective-J) [10:11] botanicus_ has joined the channel [10:20] elliottcable: eww Objective-J [10:26] jasondavies has joined the channel [10:30] DamZ has joined the channel [10:31] spoob: elliot; I guess we don't think alike.:) [10:31] elliottcable: certainly not [10:32] spoob: I think Objective-C is what you end up with when you've tried all the others and find out that all of them suck, so at least Objective-C has controlled suckage [10:33] spoob: Your language will suck too. It will be great in the areas that you care about, and it will bite ballbags in other places [10:43] micheil has joined the channel [10:45] rolfb has joined the channel [11:01] tlrobinson: elliottcable: get over it [11:02] elliottcable: spoob: lol [11:02] elliottcable: tlrobinson: eh? [11:02] elliottcable: spoob: I looove me some ObjC [11:02] elliottcable: spoob: but fuckno ObjJ [11:03] spoob: I don't see how you can like one and not the other [11:03] elliottcable: … because one’s Objective-C, and one’s very much *not* Objective-C? [11:03] elliottcable: Objective-C is *great* at what it’s good at. It’s not for the web, though [11:04] spoob: If Objective-J was more like Objective-C, then it would be crippling the Javascript side of the language. [11:04] elliottcable: it *is* crippling the JS side of the language, by not being JS! [11:04] elliottcable: that’s my problem with it. [11:04] tlrobinson: elliottcable: how so? it adds *exactly* the same things to javascript that obj-c adds to c [11:04] spoob: As it is, Objective-J is very different from Objective-C in ways that are due to unhampered access to Javascript. [11:04] elliottcable: Whoever came up with it should have stuck to Objective-C where Objective-C is great, and JS where JS is great [11:04] felixge has joined the channel [11:04] elliottcable: not tried to make some hybrid [11:04] tlrobinson: and it's a *superset* [11:04] tlrobinson: ACTION came up with it [11:05] tlrobinson: well, helped [11:05] elliottcable: hah [11:05] elliottcable: well then, explains a lot [11:05] tlrobinson: fuck you [11:05] elliottcable: was wondering where ‘get over it’ came from d-: [11:05] tlrobinson: seriously [11:05] spoob: Objective-J is full unhampered Javascript. It is not limited to Objective-C constructs, and there are no ways in which C limitations have been imposed on Javascript. [11:05] tlrobinson: i'm sick of your shit [11:05] elliottcable: seriously? fuck yourself [11:05] elliottcable: I have a hater! Great d-: [11:06] spoob: ok, I gather you two don't like each other, but back to my point... [11:06] elliottcable: tlrobinson: anyway, in all seriousness, I’m an opnionated jackass; you dislike me, /ignore exists for a reason. Yay! [11:06] elliottcable: tlrobinson: have a nice life, etc [11:07] tlrobinson: i don't hate you, i hate your attitude [11:07] tlrobinson: grow up [11:07] tlrobinson: i'll leave it at that [11:07] elliottcable: hah [11:07] elliottcable: Indeed, and telling me to grow up is real mature as well! [11:07] elliottcable: I love the implication that, since I disagree with you, I couldn’t possibly, I dunno, have my own opnions, or, eh, be an adult or something [11:08] elliottcable: ACTION shrugs [11:08] tlrobinson: plenty of people disagree with me, i've never felt compelled to call them out on their attitude before you [11:09] tlrobinson: lets take this private [11:09] spoob: tlrobinson; he could have Asperger's or partially present on the autistic spectrum, so there's a chance of some pre-existing condition [11:10] felixge: wow, lots of cool commits last night [11:10] manamex has joined the channel [11:11] micheil: I'd just like to throw it out there that it is elliottcable who is working on that preprocessor or whatever for javascript, is it not? [11:20] tlrobinson: dear node.js and elliotcable: sorry for that outburst [11:21] elliottcable: heh yep [11:22] elliottcable: we worked it out a bit in privmsg [11:22] elliottcable: micheil: nah, it is elliottcable who is eating his own past words and writing a *second* preprocessor [11:23] elliottcable: micheil: the reasons for which I hate things like Objective-J and MacRuby (I love MacRuby, mind you, but I hate how most people use it) are the exact reasons why I wrote JESS [11:23] elliottcable: micheil: meh, I said that backwards; but yeah. There are slight differences, but generally speaking, JESS is no different than those things I hate so much. /-: [11:24] hassox: halorgium: still here [11:47] botanicus_ has joined the channel [11:50] mies has joined the channel [11:57] manamex has left the channel [11:57] voxpelli-laptop has joined the channel [12:08] halorgium: hassox: kinda [12:08] hassox: just saw you mentioned jsgi before [12:08] hassox: they have bolted on async [12:09] hassox: imho it doesn't actually help much [12:09] halorgium: where is the spec? [12:09] hassox: 1 sec [12:09] tlrobinson: hassox: i can answer questions about jsgi [12:09] tlrobinson: (i started it) [12:09] hassox: tlrobinson: hey man [12:09] hassox: oh cool [12:10] tlrobinson: though i'm not 100% familiar with the new async stuff [12:10] hassox: tlrobinson: my concern with it, and please help me understand if I'm on the wrong track [12:10] tlrobinson: i think we intend for it to be as functional as node's async http interface [12:10] hassox: what do you mean [12:11] tlrobinson: i mean you'll be able to implement node's http interface on AJSGI [12:11] hassox: halorgium: http://jackjs.org/jsgi-spec.html [12:11] halorgium: tlrobinson: http://github.com/halorgium/rack2/blob/master/examples.rb <-- my rack async prototype [12:11] halorgium: hassox: yer, found it [12:11] tlrobinson: with the same non-buffering async semantics [12:11] hassox: tlrobinson: my concern is that middleware will primarily be sync in nature [12:11] tlrobinson: the one on jackjs.org is old [12:11] halorgium: hassox: did you see my middleware impl for async? [12:12] hassox: halorgium: nope [12:12] hassox: halorgium: ruby? [12:12] halorgium: http://github.com/halorgium/rack2/blob/master/examples.rb#L64-96 [12:12] halorgium: yip [12:12] hassox: looking [12:12] tlrobinson: i think this is the latest spec http://wiki.commonjs.org/wiki/JSGI/Level0/A/Draft2 [12:13] tlrobinson: though it doesn't mention much about async [12:13] halorgium: tlrobinson: dislike the inability for middlewares not to be async :/ [12:13] hassox: halorgium: that's using rack 2 with a real response object right? [12:13] hassox: tlrobinson: looking [12:13] halorgium: hassox: that works, i've impl'd mongrel and thin handlers [12:13] hassox: halorgium: nice : [12:13] tlrobinson: halorgium: with promises it should work as both sync and async [12:14] hassox: tlrobinson: question though [12:14] hassox: why support both? [12:14] hassox: it seems that in an evented system, events should rule [12:14] hassox: and callstacks should be minimised, especially when there's the chance that there will be IO waiting right? [12:14] halorgium: tlrobinson: but how do i defer the body until it is ready? [12:14] tlrobinson: hassox: i think the middleware concept is incredibly powerful [12:15] hassox: tlrobinson: agreed [12:15] hassox: but I'm not convinced that callstack based is best [12:15] hassox: tlrobinson: what happens for eg in this case [12:15] hassox: ACTION gists [12:15] halorgium: hassox: rack2 is callstack based [12:15] halorgium: but in both directions [12:15] hassox: halorgium: ? [12:16] hassox: tlrobinson: gimmie a sec to gist this up [12:16] halorgium: handler.run, a.start, b.start, c.start, c.send_header, b.send_header, a.send_header, handler.send_header, c.send_body, b.send_body, a.send_body, handler.send_body, c.finish, b.finish, a.finish, handler.finish [12:16] halorgium: that is the flow [12:16] halorgium: the stack is handler(a(b(c())) [12:17] hassox: so it's one request at a time o.O [12:17] halorgium: no [12:17] tlrobinson: where is rack2 discussed? [12:17] tlrobinson: ACTION hasn't seen it yet [12:18] halorgium: c.send_header is called when the IO is ready [12:18] halorgium: tlrobinson: #eventmachine [12:18] halorgium: i just hacked this out yesterday [12:18] tlrobinson: ah [12:18] hassox: tlrobinson: how do I get access to the next middleware? [12:18] hassox: in jsgi [12:19] tlrobinson: the standard pattern is function Middleware(app) { return function(env) { do stuff; response = app(env); do more stuff; return response }; } [12:19] halorgium: tlrobinson: the difference is that the app does not return data, it calls methods to send data [12:20] hassox: halorgium: right so you're returning quickly and letting callbacks do the work? [12:20] halorgium: hassox: yes [12:21] hassox: kk [12:21] spoob: will you be using Javascript 1.7 yield in that pattern? [12:21] tlrobinson: no [12:23] tlrobinson: for async "response" will be a promise, which you can add a callback to, then return a different promise, etc [12:23] tlrobinson: you should get in contact with kris zyp and i think deanlandolt. they've been working on the async parts [12:23] hassox: nearly there [12:23] hassox: http://gist.github.com/269345 [12:24] halorgium: tlrobinson: we've been talking about the oddities of implementing async on sync rather than the inverse [12:24] hassox: considering that MiddleOne and MiddleTwo come from different libraries how would it work [12:24] hassox: halorgium: have you seen chain? [12:25] hassox: shameless promotion [12:25] halorgium: hassox: yer, had a look [12:25] hassox: tlrobinson: pls see gist ^ ^ [12:25] halorgium: but it is JS [12:25] hassox: yes [12:25] tlrobinson: hassox: looking [12:25] hassox: but I think the concept can be applied to any evented language [12:25] hassox: as in [12:25] hassox: one that does events on instances [12:26] hassox: halorgium: are you in nz still or back to sf? [12:26] tlrobinson: hassox: i think middleware can be written to be async compatible and/or sync comatible [12:26] hassox: tlrobinson: so you can't use them interchangably together? [12:26] tlrobinson: well, if you make it both sync and async compatible it could [12:26] hassox: k [12:27] tlrobinson: as for how exactly that would work, i'm not sure [12:27] hassox: so if you check for a promise object otherwise do sync stuff [12:27] tlrobinson: but yeah, it gets a little complicated [12:27] halorgium: hassox: NZ [12:27] hassox: tlrobinson: tbh this is what makes me a little uncomfortabe [12:27] hassox: halorgium: when do you go back? [12:27] halorgium: 10th [12:28] spoob: halorgium; have you seen my sheep? they swam over to your place :) [12:28] halorgium: spoob: yer, ate em for tea tonight [12:28] hassox: tlrobinson: are you from the ruby world? [12:28] tlrobinson: yeah. and the Q.when() function from the promise people lets you not worry about whether its async or sync [12:28] hassox: tlrobinson: what's that about then? [12:28] tlrobinson: hassox: no, but i dabble [12:29] tlrobinson: Q.when(promise, callback, errback, progress) [12:29] halorgium: hassox: chain seems to not really support async [12:29] hassox: o.O [12:29] hassox: halorgium: you cannot use it other than async [12:29] tlrobinson: you just put the code in callback [12:29] spoob: halorgium; unless you put a RunLoop into the Chain :) [12:30] tlrobinson: and if its a promise it fires when the promise is resolved [12:30] hassox: halorgium: the only way to use it is via an event to move it from middleware to middleware [12:30] tlrobinson: btw my terminology for this stuff might be completely wrong [12:30] hassox: tlrobinson: yeah I'm the same ;) [12:30] halorgium: hassox: but you're saving the "body" of the response [12:30] hassox: tlrobinson: interesting [12:30] hassox: halorgium: ? [12:31] hassox: halorgium: only optionally [12:31] tlrobinson: (at least that's my understanding of it. kriskowal knows it a lot better than i do) [12:31] tlrobinson: (and kriszyp) [12:31] hassox: halorgium: you can respond directly with the response object rather than use the body cache [12:31] halorgium: hassox: does that get passed through the middlewares? [12:31] hassox: tlrobinson: where's the Q stuff ? [12:31] hassox: halorgium: does what get passed through [12:32] halorgium: hassox: the body chunks [12:32] hassox: not if you're responding directly no [12:32] tlrobinson: http://github.com/280north/narwhal/blob/master/lib/events.js [12:32] halorgium: hmm, then it isn't really a middleware ... [12:32] hassox: with chain you can optionally see the response as it comes back [12:32] tlrobinson: we've been experimenting there [12:32] tlrobinson: hassox: ^ [12:32] hassox: tlrobinson: :O [12:32] hassox: you're at 280north ? [12:33] tlrobinson: yeah [12:33] hassox: I love your stuff! [12:33] tlrobinson: thanks [12:33] hassox: halorgium: you [12:33] hassox: ' [12:33] hassox: you're right, it's not like traditional middleware [12:34] tlrobinson: (narwhal isn't entirely 280north, about half is kriskowal's work plus many other contributors) [12:34] hassox: but that's because traditional middleware is setup for callstack based processing [12:34] hassox: oh you guys own narwhal? [12:34] halorgium: hassox: rack2 is middleware async-style [12:34] tlrobinson: its open source, but i started the project [12:34] hassox: halorgium: chain implements middleware optionally [12:34] hassox: tlrobinson: awesome :D [12:34] halorgium: each middleware gets the 3 events and can modify them as needed [12:35] hassox: halorgium: if as a middleware instance you want to modify the output, you can setup a callback [12:35] halorgium: http://github.com/halorgium/rack2/blob/master/examples.rb#L33 [12:35] hassox: but if you don't want to modify it, you don't set a callback' [12:35] halorgium: isn't a callback too late? [12:35] hassox: it never "comes back" through if you don't care about it on the way out [12:35] hassox: sometimes [12:36] hassox: if an endpoint directly responds to the client then yeah the callbacks are ignored [12:36] halorgium: surely endpoints should be isolated [12:36] halorgium: a backdoor defeats the point [12:36] hassox: eg if you have a web socket, it doesn't need callbacks that can modify the output [12:36] hassox: what point [12:37] halorgium: of the middlewares [12:37] hassox: we're not constrained by callstacks [12:37] hassox: why should they be forced to behave like they do in ruby? [12:37] halorgium: that isn't what i'm saying [12:37] halorgium: think about the gzip case [12:38] halorgium: what if i set the Content-Encoding header, but then don't send the data back through the middleware [12:38] halorgium: it won't get gzip'd [12:38] halorgium: i shouldn't be able to do that [12:39] hassox: but it's javascript [12:39] halorgium: when the event go back towards the handler, the callstack is backwards [12:39] hassox: just wrap the sendBody method in a gzip'd version [12:40] halorgium: hmm, i thought you said people could bypass the middleware [12:40] hassox: I agree that it's a very different mind set [12:40] halorgium: does chain not do that by default? [12:40] hassox: a middleware can choose if it wants to see the request on the way out [12:40] hassox: by means of a callback [12:40] halorgium: "see" != "intercept", right? [12:40] hassox: what do you mean? [12:41] hassox: no [12:41] hassox: intercept is correct [12:41] hassox: but it's optional [12:41] hassox: for example [12:41] hassox: if I'm want to respond directly to a client, I go ahead and send the headers and the body and finish the connection [12:41] hassox: then I don't execute those callbacks because I've already sent the response [12:42] halorgium: finish is interceptable too, right? [12:42] hassox: but normally, if I'm not responding directly, I just say env.done() and that calls the first callback [12:42] hassox: finish() can be listned to I believe [12:42] hassox: wanna skype? [12:43] halorgium: IMO it shouldn't be up to you whether you're responding directly [12:43] hassox: why not? [12:43] hassox: if I'm implementing a websocket it should be [12:43] hassox: or if I'm implementing a long open proxy then why shouldn't I be able to respond directly? [12:43] halorgium: right, but if i put a "don't finish now, but wait 2 seconds and then finish" middleware in place [12:43] hassox: yeah [12:43] halorgium: no-one should be able to bypass that [12:44] hassox: why not? [12:44] hassox: if something downstream knows it's job and knows that it can respond, why shouldn't it be able to? [12:44] halorgium: if that is the case, it shouldn't be wrapped in the "2 seconnd wait" middleware [12:46] hassox: unless you need to respond directly, you shouldn't [12:47] hassox: but by saying that you "can't" removes a whole lot of awesome [12:47] voxpelli-laptop has joined the channel [12:49] hassox: halorgium: /me is downloading skype [12:49] Sembiance: :) [12:49] halorgium: hassox: /me should sleep! [12:49] hassox: halorgium: so should /me [12:50] hassox: I have to be up for work in 5.5 hours [12:50] halorgium: hassox: me too [12:50] hassox: hhe [12:50] halorgium: cept that is early for you... [12:50] hassox: and you're 4 hours ahead [12:50] halorgium: 2am here [12:50] un0mi has joined the channel [12:51] rolfb: almost 2pm here [12:51] hassox: halorgium: so what you're suggesting is that every chunk should pass through every bit of middleware forcefully? [12:51] hassox: if it needs to or not? [12:51] halorgium: hassox: if it requests that, yes [12:52] halorgium: if a middleware wants the event, the event must pass through [12:52] hassox: an event occurs after it happens though [12:53] tlrobinson: hassox halorgium i'm going to go, but if you'd like to propose ideas/changes/completely new interface/etc for AJSGI http://groups.google.com/group/commonjs is where we talk about it [12:53] felixge_ has joined the channel [12:53] hassox: tlrobinson: churs [12:53] tlrobinson: also #commonjs, usually kriskowal kriszyp deanlandolt and i are around [12:53] hassox: I"m in there [12:54] tlrobinson: ok cool [12:54] halorgium: hassox: i am calling "sendBody" an event [12:54] hassox: halorgium: right but it's kinda not [12:54] hassox: once you call sendBody it's sent [12:54] hassox: but I guess if we're talking conceptually ok [12:54] halorgium: not if it is wrapped with other code [12:55] hassox: right if it's wrapped [12:55] hassox: so what if it were to be wrapped such that you could chose to add a callback to sendHeader, sendBody and finish? [12:56] hassox: that were run prior to the actual original raw function being called? [12:56] halorgium: a callback isn't run before.. ;) [12:56] hassox: ok ok [12:56] hassox: a before function then [12:56] hassox: :P [12:57] hassox: so you add a function to mutate the args prior to going again [12:57] hassox: prior to calling the original I mean [12:59] halorgium: it would need to be wrapped though [12:59] halorgium: to all for before and after [12:59] halorgium: err, allow [13:00] hassox: agreed [13:00] hassox: but that being the case, [13:00] hassox: it should be wrapped by the low level framework rather than each piece of middleware [13:00] hassox: yes? [13:02] halorgium: hassox: the framework should do the wrapping ideally [13:02] halorgium: as long as the concept is there [13:02] hassox: k [13:02] hassox: fair enough [13:03] halorgium: http://github.com/halorgium/rack2/blob/master/procish.rb [13:03] halorgium: another option [13:03] hassox: nice [13:03] hassox: so each component becomes a little rack stack [13:04] hassox: header, body and finish [13:04] halorgium: was talking with wycats [13:04] halorgium: he hated the idea of a request object by default ;) [13:04] hassox: lol [13:04] hassox: that doesn't surprise me [13:04] hassox: I've talked about this with him before [13:04] halorgium: i should point him to JSGI ;) [13:05] halorgium: yer, this is more succint that the other impl [13:05] halorgium: you only wrap what you need [13:05] hassox: right [13:05] halorgium: but essentially the same concept [13:06] hassox: perhaps each header, body and finish could be a little dynaic builder that you add to [13:06] hassox: then they can each be called like a stack [13:09] halorgium: hassox: hmm, dunno if i want that [13:09] halorgium: do you mean iterate instead of stack? [13:09] hassox: not sure mate [13:09] hassox: just thinking out loud [13:09] hassox: I was thinking of a stack [13:10] halorgium: or you mean some helper methods to make it easier [13:10] hassox: yeah [13:10] hassox: kinda [13:10] hassox: so at the start of the request [13:11] hassox: the rack.header, rack.body, and rack.finish could be seeded with a dynamic builder [13:11] hassox: where you add blocks and things that respond to call [13:11] hassox: if you're interested in modifying stuff [13:11] hassox: that's constructed like a stack [13:11] halorgium: kinda annoying in ruby with single block param :( [13:11] hassox: iteration is not awesome in an async setup [13:14] spoob has joined the channel [13:16] jasondavies has joined the channel [13:21] alex-desktop has joined the channel [13:22] davidsklar has joined the channel [13:34] pmuellr has joined the channel [13:38] manamex has joined the channel [13:41] voxpelli-laptop has joined the channel [13:42] lattice1 has joined the channel [13:50] soveran has joined the channel [14:01] robrighter has joined the channel [14:02] mahemoff has joined the channel [14:15] kriszyp has joined the channel [14:24] jasondavies has joined the channel [14:41] Booster has joined the channel [14:52] cloudhead_ has joined the channel [14:53] anand_ has joined the channel [14:56] eviltwin has joined the channel [14:56] pjb3 has joined the channel [14:59] jed__ has joined the channel [15:00] anand_: Has anybody tried node.js with v8 embedded within a C++ application (http://code.google.com/apis/v8/embed.html) ? [15:00] erichocean has joined the channel [15:00] anand_: The essential idea is to be able to interface with certain pre-existing C/C++ libraries. [15:04] inimino: anand_: you probably want to create a thread to deal with the existing library through an async interface [15:04] anand_: Ok. How does the FFI work ? From JS to C++ and back ? [15:06] mediacoder: anand_: there is node-ffi .. http://github.com/rbranson/node-ffi ..not sure about its status tho [15:06] inimino: anand_: take a look at libeio, and the modules in the node source [15:07] anand_: node-ffi looks interesting. [15:08] anand_: Thanks - the sqlite nodejs-ffi example fits with my mental model. [15:09] anand_: Off to see if I can whip an example control flow tying JS and my library! [15:09] inimino: :) [15:09] jasondavies has joined the channel [15:15] bryanl has joined the channel [15:20] n8o has joined the channel [15:21] n8o: sorry I've been afk for 16 hours, but gotham as a programming font, isaacs? [15:24] kriszyp: how do you print the stack trace of an error (when you catch it) in node? [15:25] inimino: error.stack? [15:25] inimino: that's spidermonkey, at least [15:25] kriszyp: perfect, thank you [15:26] inimino: kriszyp: yep [15:26] inimino: node> (new Error).stack [15:26] inimino: "Error\n at EventEmitter. 1 [15:58] kriszyp: b -> 2 [15:58] kriszyp: var {a, b} = {a: 1, b: 2}; [15:58] kriszyp: a -> 1 [15:58] kriszyp: b -> 2 [15:58] kriszyp: but it is not in v8 [15:58] felixge_: jed__: nothing wrong with regex, but I think (fab) should define the structure of your site, not the regex mapper. That should be a separate filter before [15:58] felixge_: kriszyp: yeah - that sucks : | [15:59] felixge_: it is pretty cool [15:59] jed__: felixge_: i see your point. one of thing things i think i'm going to implement is "middleware" for each node, which would allow people to implement their own filters. [15:59] spoob: one reason why regexp would suck more is because then fab wouldn't be able to parse it and have common selse default actions [16:00] spoob: you could have a plugin regexp filter and a plugin fab filter? [16:00] jed__: felixge_: so when a (fab) object takes a single function, it creates a wrapper around the rest of the request hierarchy. [16:00] felixge_: regex are broken in JS anyway, no negative lookbehind? Come on, this hurts ;) [16:00] felixge_: jed__: yeah I guess [16:00] brosner has joined the channel [16:01] kriszyp: jed__, in regards to middleware, have you looked at all at JSGI middleware? Don't know if that is a good fit for you what you are doing or not... [16:02] jed__: kriszyp: sure sure. in an ideal world you could just drop in a JSGI middleware anywhere in the hierarchy. [16:02] spoob: tlrobinson is also working on AJSGI if you're interested in async calls [16:03] kriszyp: I've been working on it too [16:03] kriszyp: http://github.com/kriskowal/narwhal/blob/master/lib/events.js [16:03] kriszyp: oops [16:03] kriszyp: http://github.com/kriszyp/jsgi-node/ [16:03] jed__: i'm thinking of making (fab) exclusively async. [16:03] jed__: so it would need something like that. [16:03] kriszyp: that is what I am using for running my async JSGI middleware on top of node [16:04] jed__: but i'd like to wait until something resembling an agreed node/commonjs standard emerges. [16:04] spoob: ah, a connection between two useful things. A nice moment. :) [16:05] kriszyp: I feel like things have stabilized well with async JSGI in CommonJS, but maybe I am being overly optimistic [16:05] kriszyp: And I don't think async JSGI needs to eliminate the value of Node's HTTP more eventish interface as well [16:07] jed__: kriszyp: sure. i'm going to try to make (fab) JSGI by default. [16:07] kriszyp: cool [16:07] kriszyp: do you have a link for fab? [16:07] jed__: kriszyp: (i also would like (fab) to run in the browser... that is first up after async) [16:07] jed__: http://github.com/jed/fab/ [16:09] kriszyp: looks cool [16:09] manamex has left the channel [16:09] spoob: jed; now I understand the ()'s do nothing, I can see how you really stretched JS into a DSL now [16:09] kriszyp: heh, so you are the one that helped me with jsgi-node :) [16:10] spoob: the idea of chaining functions instead of methods is quite brilliant [16:10] felixge_: spoob: +1 :) [16:11] jed__: yeah, the whole goal is to use javascript w/o pre-processing. [16:11] jed__: there are so many cool things, most recently coffeescript, that i'd love to use but would like to be real javascript. w/o abusing "with" etc. [16:12] jed__: kriszyp: guilty.... tho all i did was move stuff around, heh. [16:13] kriszyp: well, thank you! [16:14] spoob: jed; you've sort of got a universal solution for how DSLs are written in Javascript. Other people would define their own (fab) objects and have their own structures [16:14] spoob: I'm just musing about nested functions as opposed to nested objects [16:14] jed__: spoob: i thought about that. it could definitely be a universal approach, but i'm keeping it specific to HTTP for now. [16:16] jed__: spoob: but the idea of function chaining is one i really like. if only functions had a real prototype chain i think it'd take off. [16:18] spoob: jed; there is some overlap between objects with functions and function chaining, so how about something evil like { key: "value", "yep": blah } ( fab stuff ) - eg, extend objects the same way that you've extended the fab object. Reading that again shows that I'm not right, but there's an idea in that messy thought [16:19] spoob: kind of setting up a data object, then chaining through it [16:19] jed__: spoob: i'm not sure i understand. [16:20] spoob: instead of (fab) (then function chaining), you could combine it with the more normal approach of { key: value, method: function(){}, etc: blah }, and then chain that through functions [16:20] jed__: i think the best way to think about it is this: a (fab) function is just an ordinary object with its own state and methods. the difference is that it's callable, and when called it dispatches to the appropriate method based on argument signature. [16:21] spoob: right, so could you load up the fab object with data that could be internal to the chained functions? [16:21] jed__: hmmmm. the chained functions already have their internal data. each (fab) object is its own function. [16:22] jed__: you can send a request to any point in the hierarchy and it'll behave the same. [16:22] davidsklar has joined the channel [16:22] spoob: ok, well that was the idea, so I'm glad to have communicated it :) [16:23] jed__: spoob: i'll make all of that clearer when i finally launch and put up some real documentation. [16:23] brosner has left the channel [16:24] johan-s has joined the channel [16:31] jed_ has joined the channel [16:38] binary42 has joined the channel [16:41] jamiew has joined the channel [16:56] rolfb has joined the channel [17:11] cloudhead_ has joined the channel [17:12] pdelgallego has joined the channel [17:13] micheil has left the channel [17:17] sudoer has joined the channel [17:27] n8o has joined the channel [17:29] eddanger has joined the channel [17:33] n8o has joined the channel [17:39] qFox has joined the channel [17:42] ryah_away: felixge_: ping [17:42] felixge_: ryah: pong [17:43] felixge_: ryah: sorry, I initially was using mkdir but must have changed it to a second stat call [17:44] jamiew has left the channel [17:44] felixge_: I think both were behaving exactly the same [17:44] felixge_: anyway, can't see the patch you mention in the mailing list [17:44] ryah: felixge_: just resent it [17:44] felixge_: ryah: k [17:44] felixge_: wll try in a sec [17:49] n8o has joined the channel [17:50] felixge_: ryah: ok, doesn't seem to fix the test [17:50] felixge_: trying with clean compile again now [17:51] ryah: meh [17:51] felixge_: hm, no luck [17:51] ryah: felixge_: the test should have errbacks in case the file doesn't exist [17:52] felixge_: ryah: yeah [17:52] felixge_: ryah: can you reproduce the issue when you run the file with /tmp/foo existing so? [17:53] ryah: felixge_: i'm not sure exactly what that test is supposed to do, actually [17:53] felixge_: ryah: oh! sorry : ). It is supposed to output "stat, mkdir, Done" in that order [17:53] felixge_: but 9/10 times it hangs on "mkdir" [17:53] felixge_: let me fix the mkdir thing [17:54] felixge_: that was really confusing, I was on the brink of madness when I submitted the test and didn't spot the wrong name and stuff [17:55] ryah: it doesn't hang for me [17:55] felixge_: ryah: never? [17:55] felixge_: I get the issue 9/10 times [17:55] felixge_: so maybe you need to try a few times [17:55] ryah: it doesn't appear so [17:56] felixge_: ryah: you are running http://github.com/felixge/node/blob/b7f0c2d76eddcc61bbb5b7a05392e40510912b4b/test/mjsunit/test-mkdir-eio-race.js on top of HEAD with node_g right? [17:58] ryah: yes [17:58] ericflo has joined the channel [17:59] ryah: so the race condition persisits, this test just doesn't demonstate it on my computer [17:59] felixge_: that sucks [17:59] felixge_: you are on your laptop? [17:59] ryah: yeah [18:00] felixge_: hm the race condition is probably I/O and/or CPU bound [18:00] ryah: yes [18:00] felixge_: but I'm seeing the same behavior in my virtual machine which has very slow I/O [18:00] felixge_: so wtf [18:00] ryah: i think this test should be fixed up [18:00] felixge_: yeah [18:00] ryah: right now it depends on this file existsing [18:00] felixge_: I'm doing that right now [18:01] ryah: it should exit with error code 0 on success [18:01] ryah: and either run infinitely or exit with error 1 on failure [18:01] felixge_: ryah: I could also timeout after 1s [18:01] felixge_: as it should not take longer to call stat on a single file [18:02] ryah: sure [18:02] martint-t has joined the channel [18:02] felixge_: ok, will have it ready in 3-5min [18:03] jed_ has joined the channel [18:04] felixge_: ryah: hah, somewhat good news. The test pases for me with node_g now [18:04] felixge_: but not with the regular build [18:07] jasondavies: what's node_g? [18:07] jasondavies: ah, debug build [18:07] felixge_: ryah: http://gist.github.com/269563 [18:07] felixge_: this one passes for me with node_g, but times out with the regular build [18:09] felixge_: ok, getting groceries, brb [18:09] felixge_: ryah: let me know if you can reproduce the issue with the normal build [18:10] jasondavies: reproduces over here [18:10] jasondavies: (normal build) [18:13] r11t has joined the channel [18:21] scudco has joined the channel [18:23] orlandov: ++ to whomever created http://wiki.github.com/ry/node/ecma-5mozilla-features-implemented-in-v8 [18:27] isaacs has joined the channel [18:29] bentomas1 has joined the channel [18:32] ryah: felixge_: can you do it without wait() ? [18:32] ryah: your test isn't working for me [18:33] ryah: that is, it is working [18:33] ryah: what if you just do a loop and state the file? [18:33] ryah: stat [18:38] rtomayko has joined the channel [18:41] bentomas1: ryah: have you thought more about deferreds/promises? I think we are all kind of waiting on you to decide on an API re this thread: http://groups.google.com/group/nodejs/browse_thread/thread/4a1ce27a1f588a7f/ddb847397104824f?q=Promise&lnk=nl& [18:46] n8o has joined the channel [18:46] n8o has joined the channel [18:53] sudoer has joined the channel [18:55] bentomas1: ryah: I started trying to make the eventEmitter API chainable so, that we could then make the Promises use those for chaining but apparently I can't write in c++. Is the eventEmitter emit function written in c++ for performance reasons? [18:56] bentomas1: ryah: would we be interested in a patch for eventEmitter that allows chaining in pure javascript? [18:56] felixge_: bentomas1: I started working on a new promise branch today that is inline with commonjs promises [18:56] kriskowal has joined the channel [18:58] bentomas1: felixge_: that is very exciting! are you going to use the code from Dojo you changed to suite our needs or are you writing from scratch? Ryan made it sound like we would need to do it from scratch to get it accepted... [18:59] hassox has joined the channel [19:00] isaacs_ has joined the channel [19:02] jcrosby has joined the channel [19:04] hassox: hallo ppl [19:04] isaacs: anyone else thing that the "mjsunit" directory is a little bit redundant? why do we have that? why not just "test/test-blah.js"? [19:04] isaacs: s/thing/think/ [19:06] felixge_: isaacs: I think its there b/c ryan might wants to add C++ tests at some point? [19:06] isaacs: ah, that kinda makes sense, i guess... [19:06] isaacs: it doesn't much matter, since i just do "make test" to run them anyhow [19:07] felixge_: ryah: so you are saying the test does not throw an exception for you or it does? [19:08] felixge_: as far as just doing a loop goes, I wasn't able to get any results with that. I do suspect that the problem occurs as part of the module loading [19:11] jcrosby has joined the channel [19:17] voodootikigod has joined the channel [19:20] tlrobinson: jed_: after playing with fab i seriously contemplated whether it would be possible to bend js syntax with lots of parens into a lispy language :) [19:21] jtoy has joined the channel [19:21] jed_: tlrobinson: probably, right? i mean, it's basically the same thing as passing a huge array of arrays to a single "evaluator". [19:22] jed_: tlrobinson: (i was looking at jspec, and its dsl is ripe for that kind of approach) [19:29] bentomas1: felixge_: Did we ever come to a conclusion about whether or not Errors that are thrown would be caught? [19:29] felixge_: bentomas1: I think they should be caught and if there is no handler to catch them they should bubble up [19:30] bentomas1: felixge_: so do you mean errBack functions or try/catch blocks? [19:31] felixge_: bentomas1: I think errbacks should be the logical counterpart to exceptions, so if you don't explicetely handle an error, it should bubble up and crash node [19:31] felixge_: i.e. throw new Exception() and promise.emitError() are the same thing [19:36] bentomas1: sounds great [19:36] bentomas1: well, keep up the good work [19:38] johnw_ has joined the channel [19:39] felixge_: bentomas1: I'm interested to see your ideas on event emitters as well, I'm just not sure if they should support the same kind of chaining or not [19:39] JimBastard has joined the channel [19:39] felixge_: they are quite a different beast [19:39] JimBastard: what would caus my browser to constantly show the "loading" icon when browsing pages on my node server? happens cross browser [19:40] JimBastard: im pretty sure im doing a standard response, setting the header, sendBody() and then .finsh() [19:41] bentomas1: felixge_: I think I have come to the same conclusion. Promises save the return value so that if any further callbacks are added they can be passed the that value. EventEmitters definitely should not do this. Additionally, Promises wait for other Promises to finish before calling next callback. Again, I don't think EventEmitters should do this. EventEmitters, I think, should be lightweight and quick. [19:41] bentomas1: felixge_: so even if you were to make EventEmitters chainable, I don't think they could be reused in Promises [19:50] eviltwin has joined the channel [20:01] JimBastard: any clue as to why multipart.parse(req).addCallback(function(httpParams) { isn't firing for posts? [20:01] JimBastard: got it working on one project but its acting wierd in this one [20:02] JimBastard: node gets all unresponsive and has to be killed [20:04] kriskowal: felixge_ have you looked at the events module i wrote? [20:05] felixge_: kriskowal: yeah, seems to be based on JS features v8 doesn't support [20:05] kriskowal: it's intended to clarify emitters/promises [20:05] kriskowal: which features? [20:05] kriskowal: oh, Object.create; that's patchable [20:05] kriskowal: Object.create and Object.freeze are implementable in ES3 [20:05] kriskowal: at least, to the extent that the code will work, if not securely [20:05] JimBastard: dumb question, how do i add the onError callback to multipart.parse() ? [20:06] JimBastard: http://nodejs.org/api.html#_multipart_parsing [20:06] kriskowal: you need this http://github.com/280north/narwhal/blob/master/engines/default/lib/global-es5.js [20:06] felixge_: kriskowal: give me 2min, wrapping up dinner then I'll take another look [20:06] kriskowal: catch you after my lunch then :P [20:06] kriskowal: about an hour [20:15] bryanl_ has joined the channel [20:21] bry has joined the channel [20:22] felixge_: JimBastard: you mean if the multipart data is invalid? [20:28] JimBastard: felixge_ maybe thats the case, i put it down for the moment. ive got to test more [20:28] felixge_: JimBastard: in general you would just do '.addCallback(...)' [20:28] JimBastard: for some reason though in this app when a form post happens the request just hangs [20:28] felixge_: but I ythink I'm currently not doing any validation on the multipart stream [20:29] felixge_: JimBastard: are you sure you are sending multipart data? [20:29] JimBastard: maybe the form isn't encoded right [20:29] JimBastard: but if so it should still error gracefully [20:29] JimBastard: let me pastie one sec [20:30] felixge_: JimBastard: yeah, lets get this fixed [20:31] jcrosby has joined the channel [20:32] JimBastard: so something like this... [20:32] JimBastard: http://gist.github.com/269685 [20:32] JimBastard: its pretty basic [20:32] JimBastard: sup jcrosby [20:33] jcrosby: sup JimBastard [20:33] jed_ has joined the channel [20:34] JimBastard: you see that felixge_ [20:40] felixge_: JimBastard: re, looking now [20:40] felixge_: JimBastard: where is the form html? [20:47] JimBastard: its just a standard form, i left out the enctype property [20:47] JimBastard: so im assuming its erroring [20:48] JimBastard: how can i catch errors [20:55] felixge_: JimBastard: well, right now there is no error being thrown, but I can catch the missing enctype property - let me do that [21:01] voodootikigod_ has joined the channel [21:04] JimBastard: it just doesnt make sense that the whole thing would shit itself by default if a property is missing [21:04] JimBastard: people fuck up form sumbits ALL the time [21:04] felixge_: JimBastard: You mean users or developers? [21:04] JimBastard: well im building an API [21:05] JimBastard: and webservice [21:05] felixge_: well, the name says its a multipart parser - so using it with non-multipart content isn't exactly defined behavior [21:05] felixge_: :) [21:06] felixge_: but I'm working on a patch that will look at the header to see if it has a boundary and throw an error if not [21:06] JimBastard: word [21:08] r11t has joined the channel [21:20] isaacs_ has joined the channel [21:28] hassox has joined the channel [21:28] mikeal has joined the channel [21:29] felixge_: ryah: I'm seeing random "(evcom) setsockopt(SO_NOSIGPIPE) Invalid argument" on HEAD when running the multipart test case [21:32] sztanphet has joined the channel [21:33] voodootikigod has joined the channel [21:44] DamZ has joined the channel [21:48] felixge_: JimBastard: http://github.com/felixge/node/commits/multipart [21:48] felixge_: sending ryah an email to the mailing list to pull those in [21:52] isaacs has joined the channel [21:52] orlandov: anyone have a sense for how soon the net2 branch will be merged to master? [21:53] felixge_: orlandov: ryan said a few weeks when I asked him a few days ago [21:53] orlandov: cool [21:53] hassox: orlandov: what's in the net2 branch? [21:54] orlandov: hassox: http://github.com/ry/node/blob/net2/lib/net.js [21:54] orlandov: i'm not an expert but i think better support for binary protocols [21:54] JimBastard: cool thanks felixge_ [21:54] orlandov: as well as doing more stuff from JS [21:54] hassox: sockets too :) [21:55] felixge_: the main thing about the net2 branch is that pretty much all networking code is moved to JS [21:55] orlandov: yeah! [21:55] orlandov: so i may not have to hack C++ much more [21:55] felixge_: which means lowly JS hackers like me can mess with it :) [21:55] orlandov: hehe [21:55] hassox: :) [21:55] orlandov: figures that i would learn how to do all that from C++ and then have it taken away [21:55] felixge_: I mean I can write some C++, but I'm easily 1-2 orders of magnitude slower than with JS : ) [21:56] orlandov: felixge_: i hear ya [21:56] orlandov: before this last time i'd touched c++ was 10 years ago :\ [21:56] felixge_: orlandov: don't worry, there is still enough C++ pain left for a few years to come :) [21:56] felixge_: I'm not worried [21:56] orlandov: let's just say it's not like relearning to ride a bike [21:56] mattly has joined the channel [21:56] orlandov: felixge_: it's not that bad though, tbh. the c++ in node is some of the best i've seen [21:56] orlandov: it's pretty accessible [21:57] gwoo has joined the channel [21:58] inimino: it's mostly glue [21:59] orlandov: so i think i'm going to do a talk on Node at the next vancouver perl mongers [22:00] felixge_: orlandov: Yeah, Ryan is a genius to me when it comes to simplicity [22:00] felixge_: He can make really difficult stuff look very simple without huge abstraction patterns [22:00] orlandov: felixge_: i know... i hate to be a gushing fanboy... [22:00] orlandov: and getting API's right is hard [22:01] orlandov: and i know the work's not done yet, but i'd say it's pretty damn good [22:01] felixge_: yeah [22:01] mikeal has joined the channel [22:01] felixge_: its been pretty good since I started using node and has only improved over time [22:02] felixge_: and the docs are pretty nice [22:02] voxpelli-laptop has joined the channel [22:02] felixge_: I hope somebody is working on a mysql driver :) [22:02] felixge_: that would really rock [22:03] voxpelli-laptop: Anyone know an Atom and/or RSS parser that could be made to work with NodeJS? [22:03] felixge_: That whole NoSql business has really led me to appreciate mysql for some reason. [22:04] felixge_: voxpelli-laptop: nope, you'd probably need a forgiving XML parser. Tons of RSS feeds out there are broken like crazy [22:05] voxpelli-laptop: felixge_: Yeah - that and the flexibilities of xml and the standards (and the non-standard that RSS is) makes it very painful to fix yourself - that's why I want someone elses code ;) [22:05] inimino: postgres ≫ mysql [22:05] inimino: voxpelli-laptop: you'll want a parser dedicated for that purpose, maybe find a python one and run it in a separate process [22:06] felixge_: inimino: postgres == stored procedures, meh [22:07] felixge_: voxpelli-laptop: http://simplepie.org/ this is pretty good PHP one I used before [22:07] inimino: felixge_: well, yeah, that's a feature... [22:07] inimino: (you'd rather not have it?) [22:07] inimino: that's the one I had in mind [22:07] felixge_: inimino: yeah, I hate. [22:07] voxpelli-laptop: felixge_: Same here :) SimplePie is really good [22:08] inimino: though I forgot it was PHP [22:08] inimino: felixge_: ah, well, it's the logical evolution of the RDBMS [22:08] felixge_: inimino: I don't even like stored procedures with CouchDB [22:08] voxpelli-laptop: Hmm - if I could fetch the feed from a source I could use Google AJAX Feed API [22:09] inimino: felixge_: MySQL has just enough to be useless for any real work IMHO... [22:09] inimino: but I prefer to go the other way to do away with SQL altogether [22:09] felixge_: inimino: useless for any real work? [22:09] felixge_: that would depend on your definition of real work :) [22:10] orlandov: pg ftw [22:10] felixge_: bah, you guys are all procrastinating in IRC, so stop lecturing me about real work :) [22:10] orlandov: haha [22:10] felixge_: I get off the hook for being in UTC+1 :) [22:11] inimino: ACTION was multitasking [22:11] felixge_: I think multitasking is a myth [22:12] inimino: it depends what tasks they are [22:12] felixge_: To me its just a form of procrastination that makes you feel like you are super busy, but usually leads to even less results than spending 10% of that time fully focused on 1 task [22:12] felixge_: hm, well lets say I've never been able to take my multitasking further than checking my email while the coffee is brewing [22:13] inimino: you can certainly eat and read IRC channels at the same time [22:13] jed has joined the channel [22:14] inimino: but, I'm clearly procrastinating now :-) [22:14] inimino: ACTION → work [22:14] felixge_: inimino: yeah, I can tell from the stains on my keyboard about the usefulness of that one :) [22:16] jed: kriszyp: the current jsgi-node doesn't match the spec. [22:17] jed: kriszyp: is this the one i should be going off of? http://wiki.commonjs.org/wiki/JSGI/Level0/A [22:17] kriszyp: I'm sure it doesn't :/, where did I mess up? [22:17] jed: s/method/requestMethod/ [22:17] kriszyp: http://wiki.commonjs.org/wiki/JSGI/Level0/A/Draft2 [22:17] kriszyp: is the latest [22:17] jed: ah, okay. [22:17] kriszyp: let me push my latest checkins too [22:18] jed: kriszyp: did you fix to match the new url module too? [22:18] kriszyp: no, what should be done there? [22:18] kriszyp: Just pushed a couple minor fixes [22:19] kriszyp: I'll pull any changes you make if you know what needs to be changed [22:19] jed: request.uri is now request.url, and it's not parsed. [22:19] jed: (uri library is deprecated) [22:19] kriszyp: oh, ok [22:19] CIA-78 has joined the channel [22:19] felixge_: I'm wondering if the request/response object in node.js should be merged [22:19] kriszyp: so we are supposed to manually parse the url now? [22:20] jed: kriszyp: no, the url lib does that for you. [22:20] jed: kriszyp: but you need to load that lib. [22:20] jed: felixge_: what do you mean? [22:21] felixge_: jed: well, I just find myself wrapping req/res in one Request object which implements a 'respond' function for most of my projects [22:21] jed: felixge_: ha, me too. you're saying maybe the response should belong to the request? [22:21] felixge_: jed: yeah [22:22] felixge_: but request.response seems verbose [22:22] jed: felixge_: (well, i like the jsgi approach, personally.) [22:22] felixge_: jed: yeah I was reading that when I had the thought [22:23] felixge_: is JSGI aysnc [22:23] felixge_: ? [22:23] tiglionabbit: if anyone's working on the v8 mongodb client, that'd be awesome [22:23] jed: felixge_: the problem is that jsgi makes streaming responses a little bit complicated. [22:23] kriszyp: JSGI is async [22:23] jed: felixge_: but i think the overall win worth it. [22:23] felixge_: ok, I ask because I couldn't find 'async' on the page [22:23] felixge_: is there any full example? [22:24] felixge_: where I can see it? [22:24] kriszyp: yeah, I am not sure if that has made it into the draft, deanlandolt [22:24] RayMorgan has joined the channel [22:25] jed: felixge_: the basic idea is that you return a promise instead of the response. [22:25] felixge_: jed: a promise isn't a stream [22:25] felixge_: but I guess CommonJS promises have a progress event [22:25] felixge_: is that how its supposed to work? [22:25] kriszyp: http://github.com/kriszyp/jsgi-node/ has a little example of async [22:26] jed: yeah, that's what i used to understand the approach. [22:26] felixge_: I think we really need an abstract Stream Proposal :) [22:26] kriszyp: there is a progress event, but how to do streaming with JSGI has not been defined yet [22:26] kriszyp: I am of the opinion that you need streaming, than you are probably best sticking to the node api [22:26] jed: i agree with that. [22:27] kriszyp: but JSGI is an abstraction for layers that don't care about streaming, they just want to be functions that return results (or a middleware stack) [22:27] jed: is it poor form to put the node response object in env.node in the jsgi response? [22:27] kriszyp: (some results possibly being async/promises) [22:27] kriszyp: I have no objection to that [22:27] rednul_ has joined the channel [22:27] kriszyp: although it may violate assumptions that middleware might make [22:27] geoff_blair has joined the channel [22:28] jed: kriszyp: right, i'd think all bets are off once you use it manually. [22:28] kriszyp: yeah, with that warning, I think it is fine [22:28] felixge_: I think this input/output value approach is flawed [22:28] felixge_: it should be an input stream and a output stream [22:28] felixge_: and middleware should act as a stream filter [22:29] felixge_: Its really throwing away the cool stuff we can do with node just so we can stay with our mental models from python/ruby [22:30] kriszyp: yeah, you can do that, but I think a lot of people have learned from java servlet filters that that is painful [22:30] felixge_: I do see the value in adopting simple well-understood concepts that have already spread. [22:30] rednul__ has joined the channel [22:30] felixge_: kriszyp: yeah, but I blame Java - not the concept [22:30] kriszyp: but in situations where you really need to preserve streaming capabilities through a stack, I presume filter style would be needed [22:31] felixge_: there just needs to be a switch for people who want the stream rather than the full result [22:31] felixge_: kriszyp: do you have an example how midleware looks? [22:32] felixge_: * middleware [22:32] felixge_: I think I might have an idea for keeping the ease you want while supporting streams [22:32] hassox: *cough* chain *couch [22:32] hassox: cough* [22:32] hassox: ] [22:32] kriszyp: yeah, I have written a number of async JSGI middleware: http://github.com/kriszyp/pintura/tree/master/lib/jsgi/ [22:33] kriszyp: http://github.com/kriszyp/pintura/blob/master/lib/jsgi/xsite.js is a good example [22:33] kriszyp: (of async-capable JSGI middleware) [22:33] hassox: kriszyp: the q I had last night is how can you use jsgi sync and async interchangably? [22:34] kriszyp: the magic is in the when() calls [22:34] kriszyp: when the when() call gets a non-promise value, it synchronously executes the handler function and sync returns the result. Otherwise it does it async [22:36] hassox: aren't you encouraging people to stick with sync design? [22:36] kriszyp: why? [22:37] kriskowal: hassox, not really. [22:37] hassox: feels a bit bolted on tbh [22:37] jed: kriszyp: (serverName and serverPort are also missing from your adapter) [22:37] kriskowal: Q.when is a great compromise. [22:37] hassox: exactly... w [22:37] kriszyp: jed: its incomplete :/ [22:37] hassox: why should we compromise right at the start? [22:37] kriskowal: it is neither intrinsically async or sync. it can do both with a single design pattern. [22:37] kriskowal: compromise should not have a negative connotation [22:38] kriskowal: i'm not suggesting that Q.when gives you less; it gives you the best of both worlds. [22:38] kriszyp: not to change the subject kriskowal, but how is node-narwhal going? [22:38] jed: kriszyp: sure sure, i'm just comparing. serverName is the same as headers.host? [22:38] kriskowal: additionally it solves major problems with event graphs…it models transitive graceful recovery from failure. [22:39] hassox: kriskowal: but having the ability to do sync will likely mean that ppl will do sync [22:39] kriskowal: with Q.when style promises, it is possible to reconstruct the "causal" graph of a program, which is like the traceback you get with async style [22:39] hassox: why not just force each middleware to be async and allow better interleaving on the event loop? [22:40] kriskowal: Q.when *is* async. [22:40] kriskowal: and supporting async does force it to behave async. [22:40] hassox: kriskowal: I mean always [22:40] kriskowal: middleware would have to be written with Q.when, which means async would always be supported. [22:41] kriskowal: it also makes it trivial to upgrade a naive middleware to a proper asyncable middleware [22:41] kriskowal: and we can't pretend that people won't write naive code [22:41] hassox: exactly [22:41] hassox: that's what concerns me [22:41] hassox: if ppl can write a full request in a single callstack like most of the current breed of node frameworks [22:42] hassox: then concurrency, and the ability to directly respond to the client [22:42] inimino: they won't if the API doesn't allow it [22:42] hassox: two things I think node provides well, are out the window [22:42] hassox: inimino: but isn't that the point [22:42] hassox: with jack they can [22:42] hassox: jsgi [22:42] hassox: they can just have a full callstack based setup [22:43] kriskowal: i don't really follow. you might want to look into how Q.when works. [22:43] inimino: hassox: what I'm saying is, maybe you want an API that doesn't allow that [22:43] kriskowal: it's fundamentally async, and comes from E, which is async-only. [22:43] hassox: inimino: exactly [22:43] hassox: kriskowal: what I'm trying to say is that if you allow it [22:43] hassox: it will happen [22:44] hassox: if I can write an app that is fully sync, then ppl will [22:44] kriskowal: still not following. [22:44] hassox: but [22:44] inimino: hassox: then anything using that API would be async all the way down [22:44] kriskowal: i understand what you're saying, but not how it is relevant [22:44] hassox: o.O [22:44] hassox: it limits the usefulness of community code [22:44] hassox: and re-use [22:44] kriskowal: what does? [22:44] hassox: since there are two systems [22:44] hassox: two ways to do it [22:44] hassox: sync or async [22:45] kriskowal: there's only one way to write it [22:45] kriskowal: if the underlying facility is async only, it will be async [22:45] hassox: right [22:46] kriszyp: and being able to change an implementation (from sync to async) without affecting interfaces is very important, maintains critical encapsulation principles of coding [22:46] kriskowal: anyhow, kriszyp, node-narwhal gets through about half of the bootstrapping and is a shoe-in once ryan and i work out how to refactor node.cc so that main() isn't coupled to the process of constructing the primordials. [22:47] kriskowal: node-narwhal needs binary and fs module adapters, but that can all be done in a fork without upstream mergability. the only stuff that needs to go upstream is node.cc refactoring. [22:48] hassox: kriskowal: I'm failing to see how [22:48] hassox: return nextApp(request) [22:48] hassox: forces async [22:48] kriskowal: nextApp can return a promise [22:48] hassox: http://github.com/kriszyp/pintura/blob/master/lib/jsgi/xsite.js#L34 [22:48] hassox: can [22:48] hassox: but doesn't have to [22:48] kriskowal: and *will* if it's async. [22:49] kriskowal: *must* [22:49] hassox: right [22:49] hassox: so you're not forcing async [22:49] kriskowal: no, the responsibility of forcing async gets deferred to a lower level [22:50] hassox: sorry if I'm sounding thick [22:50] hassox: what lower level [22:50] kriskowal: IO [22:51] kriskowal: if nextApp cannot return a fully resolved value immediately (which would be the case for certain things like template rendering if that's all that needs to be done), it must return a promise to resolve the return value of nextApp in a future turn [22:51] hassox: so [22:52] hassox: what if I want to hold open the connection in an endpoint and respond directly to the client? [22:52] inimino: there's also the issue of what you mean by "async" [22:52] inimino: I think hassox means something more like streaming [22:52] hassox: inimino: there's that [22:52] hassox: but there's also making sure that the cpu is being used and not waiting [22:52] kriskowal: both cases are satisfied. [22:52] hassox: and there's also the benefit of concurrency by forcing middlewares to be async [22:52] kriskowal: you can defer on input or output, doesn't matter. [22:52] hassox: if you force a middleware to be asyn, then it can't hog the cpu for the full request [22:53] hassox: kriskowal: what do you mean by defer? [22:53] kriskowal: that's not necessarily true since we're talking about cooperative event loops, not a preemptive event loop, but i know what you mean. [22:54] rictic has joined the channel [22:54] kriskowal: Q.when returns a value. that value is either fully resolved (which is called a "near" reference), or it is a partially resolve "promise" (a "far" reference) [22:55] kriskowal: if it returns a "promise", it's yielding to the event loop. [22:55] hassox: right [22:55] inimino: felixge_: I've been thinking about streaming APIs lately, if you have some pseudo-code I'd be interested [22:55] hassox: kriskowal: I understand how it works conceptually [22:55] hassox: that's why the questions [22:55] kriskowal: if that promise is fully resolved in a future turn, perhaps by being partially resolved multiple times, the ok callbacks will be provided the fully resolved "near" reference [22:56] kriskowal: if that promise is broken, all error callbacks that have been registered on the promise, or any of its causal dependents, get fired in subsequent turns. [22:56] JimBastard: would it be possible to implement rtmp in node? [22:56] hassox: so how does that fit the case of a long polling endpoint [22:56] hassox: or a websocket [22:56] kriskowal: Q.when is the pin that holds it all together [22:56] kriskowal: Q.when both observes a promise and returns a promise [22:57] kriskowal: that promise can be either near or far in both cases [22:57] hassox: not sure what you mean by near or far in both [22:58] kriskowal: so, if you are faced with a "long" operation that needs to be completed in a future turn, you return a partially resolved promise, that which is returned by Q.when [22:58] hassox: right [22:58] kriskowal: a = Q.when(b, ok) [22:58] kriskowal: b can be an "immediate" or "near" value like 10. or, it can be another promise like that returned by connectToDatabase() [22:59] kriskowal: in the E world, any reference can be a promise. in JavaScript, this can be emulated by saying that any function can return a promise. if it *can* return a promise, you *must* use Q.when to observe its fulfillment [23:00] kriskowal: or one of the semantic equivalents like promise.observe('ok', ok), promise.addCallback(ok), &c [23:00] kriskowal: (except that addCallback and observe have that one critical shortcoming of not returning a promise in turn) [23:01] JimBastard: it would be bad ass to be able to stream video to flash players [23:01] JimBastard: server-side actionscript is kinda awful [23:01] kriskowal: the general rule is that any time there's a *chance* that you're calling a function that *might* need to wait for a future turn, you catch the promise in a Q.when to observe its resolution, and return the resulting promise so that someone else can observe *your* resolution [23:01] mediacoder: JimBastard: you can pseudostream (over http) [23:01] JimBastard: well, sockets [23:02] JimBastard: using html5 of a flash embed [23:02] JimBastard: over tcp [23:02] mediacoder: well, there you need rtmp for flash [23:02] kriskowal: Q.when then affords you a great deal of flexibility, it can be used to interface any function, whether or not you *know* at that API layer whether it will return an immediate and fully fulfilled value, or a promise to call back later [23:02] JimBastard: so how hard would it be to implement rtmp in node [23:02] JimBastard: im pretty sure there is a RFC for it [23:02] mediacoder: JimBastard: not sure..the spec is open [23:03] mediacoder: would also interest me [23:04] jcrosby has joined the channel [23:04] felixge_: oh wow, I missed all the fun [23:04] felixge_: inimino: no, I don't have any pseudo code other than the multipart API [23:05] felixge_: but I believe a 'complete' and 'data' as well as a 'write' method would be found in any kind of stream [23:05] JimBastard: i tried to run ab on my node app and node shat itself, i think i forgot to close a request somewhere oops [23:05] felixge_: I think a Stream is an EventEmitter which implements a minimal set of events and methods, but depending on the nature of the stream extends them with more [23:05] soveran has joined the channel [23:11] hassox: sorry kriskowal reading ^ ^ [23:11] hassox: kriskowal: something came up [23:12] hassox: kriskowal: what's this [23:12] hassox: promise.addCallback(ok), &c [23:12] kriskowal: hassox i think that the critical distinction is that "immediate" resolution is not the same as "synchronous" resolution. Q.when permits middleware to be written in such a way that they support both immediate and async returns. it happens that some immediates could be synchronous, which means that you have to prevent synchronous calls somewhere other than the middleware. [23:12] kriskowal: meaning, by not providing synchronous IO options. [23:13] hassox: what's the &c syntax? is that javascript? [23:13] kriskowal: promise.addCallback(callback):this and promise.addErrback(errback):this is the Dojo Deferred API, which NodeJS appears to support. Narwhal's events module supports it as well, but encourages use of Q.when(ok, error) since it's equivalent but returns a new promise. [23:13] kriskowal: & is latin, "et", means "and". &c means "et cetera" [23:14] kriskowal: and so on [23:14] hassox: rgr [23:14] jan____: kriskowal: smartassing with the chars? :D [23:14] kriskowal: it's a hobboy [23:14] kriskowal: *hobby [23:14] jan____: I approve. [23:15] hassox: kriskowal: ok so back to the streaming thing [23:15] hassox: can I stream from an endpoint? [23:15] kriskowal: meaning asynchronously both reading and writing? [23:15] hassox: say I want to hold open a connection from couchdb changes, and stream them to a client [23:15] hassox: yup [23:16] kriskowal: with jsgi, yes. [23:16] kriskowal: with Q.when middleware [23:16] hassox: or, another example I did the other day was to have twitter firehose emitting events and passing those out to clients [23:16] kriskowal: so you get both streaming, and recursive routing. best of both worlds. [23:16] hassox: Q.when middleware expects a resolution though right? [23:16] kriszyp: I don't think we have clear consensus on how the multi-event streaming would work on JSGI do we kriskowal? [23:16] kriskowal: no [23:16] hassox: so once you run your callback... it's done isn't it? [23:17] kriskowal: kriszyp: i have no idea what the present debate is, but last i checked it was possible [23:17] kriskowal: no. the callback can return a new promise :P [23:17] kriszyp: possible, but I think we still have a couple of different ideas on how to do it [23:18] kriszyp: it can be done with a progress events or it can be done by allowing the forEach call to return a promise (and allowing the forEach callback to be called at any time until the promise is fulfilled) [23:18] kriskowal: Q.when(connect(), function (connection) { return Q.when(connect(), function (otherConnection) { … [23:19] kriskowal: as i recall, forEach receives a writer. that's all you need for bidi. you only return a promise to forestall .finish() [23:19] kriszyp: yeah, but forEach doesn't get called if you return a promise for a response (because the forEach isn't there yet) [23:19] kriszyp: so you need to look for a promise from the forEach call [23:19] kriszyp: which works fine [23:19] kriszyp: just have to look for promises in two places [23:20] kriskowal: given that it's easy enough to Q.when, i don't think that's a problem. [23:20] felixge_: kriskowal: so I'm looking at your Q API and I'm slightly confused about the difference between 'events, signals, emitters and observers' [23:20] kriskowal: although, i don't think it's a crime to provide the writer on the request call like nodejs ajsgi [23:20] kriszyp: might be worth pointing out that if you are talking about doing comet with couchdb, hassox, that IE doesn't support streaming anyway, so in reality you usually just do one-shot responses anyway [23:21] hassox: I'm not really that interested in IE tbh [23:21] kriskowal: i think it's fine to discuss this in the ivory tower anyway. nodejs is very idealistic in its scope. [23:21] hassox: there's nothing stopping nodes from connecting to other nodes [23:21] kriszyp: if you don't have to worry about IE, you are in a tiny minority :) [23:21] hassox: kriszyp: I just mean that just because IE can't handle it, it should not be written off [23:22] hassox: as somethign that should not be done [23:22] hassox: that's a single use case [23:22] kriszyp: yeah, I understand [23:22] felixge_: kriszyp: I think the use case would be file downloads where a middleware might act as a compressor [23:22] kriskowal: so, i can see why it's not inherently obvious how they're different. that's kinduh the beauty [23:22] bentomas has joined the channel [23:22] kriskowal: an event is like a DOM event object; it carries event state. [23:23] kriszyp: yes, I don't want to give the impression that streaming is not valuable, I agree that it is [23:23] kriskowal: including the methods for stopping event propagation [23:23] mikeal: I'm writing a client that needs to continuously stay open to an HTTP server and read chunks as they get pushed to the client [23:23] hassox: doesn't the jsgi prevent me from getting hold of the response object though? [23:23] kriszyp: just saying that within application layers (that aren't usually worried about compressing files), that one shot async covers a very high percentage of use cases [23:23] hassox: and if that's the case... how can I possibly do streaming [23:23] mikeal: it's not a multipart form and I'm having a hard time finding an event I can listen to [23:24] kriskowal: an emitter is type that has a name to signal mapping. [23:24] felixge_: kriskowal: want to go PM with the Q discussion, I feel like I 'm interrupting the main discussion [23:24] kriskowal: like, an emitter might have "ok" and "error" signals [23:24] felixge_: * ? [23:24] kriszyp: and one doesn't have to use async JSGI all the way through the stack (or at all). it is tool that is available for making simple middleware app stacks [23:25] kriskowal: how bout' we come back later. i think it's good to have the explanation public. [23:25] kriszyp: and like kriskowal said, streaming with JSGI is possible, even if we haven't yet reached consensus on exactly the best way [23:26] hassox: kriszyp: kriskowal but if we're going to base entire frameworks on jsgi then we should make sure that jsgi isn't going to limit awesomeness right? [23:26] felixge_: kriskowal: ok, lets do that. Might be tomorrow for me so, 00:23 here [23:26] felixge_: I'll read through the code some more [23:26] kriszyp: its about keeping simple things simple and the advanced possible [23:27] hassox: personally I think it's a little more than that [23:27] hassox: I think it needs to make sure that apps are well behaved [23:27] hassox: in that they're not hogging the cpu for whole requests [23:27] kriszyp: sync doesn't hog cpu, it hogs threads (just to clarify) [23:28] kriszyp: but I know what you mean [23:28] kriszyp: and JSGI *is* async [23:28] hassox: kriszyp: there are no threads availabe in node [23:28] kriskowal: cpu hogging cannot be prevented with cooperative multitasking. ask mac os 9 [23:28] kriskowal: or windows 3 [23:29] kriszyp: hassox: right, thats the point isn't it? :) [23:29] hassox: exactly [23:29] hassox: since there's only one thread [23:29] hassox: requests can hog [23:29] kriskowal: node doesn't solve this problem. [23:29] kriskowal: workers might [23:29] kriszyp: of course at some point node will support multi processes/workers [23:29] kriskowal: but at that point, the sync/async debate is moot [23:29] kriszyp: or it needs to [23:29] hassox: node doesn't solve the problem, but it makes a solution possilbe [23:30] kriskowal: jsgi does not preclude the solution [23:30] hassox: by ensuring that we divide up a request into different events / promises / callbacks etc then we can interleave requests [23:30] kriskowal: totally orthogonal issues [23:30] hassox: I don't think they are [23:30] bentomas has left the channel [23:30] kriskowal: jsgi does not preclude eventing [23:31] hassox: I know... [23:31] kriskowal: it does not preclude *enforced* eventing. [23:31] hassox: but it also doesn't prevents callstacking entire requests [23:31] kriskowal: neither does node's api [23:31] soveran has joined the channel [23:31] hassox: as soon as a request is callstacked, then it's not concurrent and conccurrency isn't possible [23:31] kriskowal: what prevents callstacking a request is the non-existence of blocking io [23:32] hassox: node doesn't aim to provide a framework for building apps on [23:32] hassox: well not for building middleware based apps [23:32] hassox: what we're talking about is that 1 level higher abstraction [23:33] hassox: where we can enforce splitting requests up on the event queue [23:33] kriszyp: right, there is no reason that node needs to implement JSGI [23:33] hassox: agreed [23:33] kriskowal: yet there is no reason it cannot [23:33] hassox: why should it though [23:33] hassox: node is a lower level [23:33] kriskowal: because middleware and routing is a fabulous abstraction [23:33] kriszyp: it is easily implementable (well implemented, it is already done) in JS [23:34] hassox: middleware is awesome I agree [23:34] hassox: I've written plenty of it in ruby [23:34] hassox: but that's part of the problem [23:34] hassox: for eg [23:34] hassox: when I came to ruby, I watched with a great deal of pain as people coded java in ruby syntax [23:35] hassox: and now I've seen it here.. people rush into node without thinking about the benefits that events and async give, and we end up with callstack based framworks that are just ports of frameworks in non-evented languages [23:36] hassox: jsgi's async addition is good, but why not make sure that we're async always [23:36] kriskowal: there's no reason to do anything asynchronous for a trivial response. why enforce async in that case? [23:37] mikeal: because javascript is async [23:37] mikeal: if you aren't async you're blocking [23:37] mikeal: blocking is bad :) [23:37] kriskowal: that's not true. [23:37] hassox: because by forcing async, you're dividing up the request and allowing interleaving [23:37] hassox: and therefore concurrency [23:37] kriskowal: you're only blocking if you're waiting for long IO. you've got to compute at some point. [23:38] hassox: agreed you do [23:38] kriskowal: when you're computing in a cooperative system, you're preventing other events from turning. [23:38] mikeal: i don't really get jsgi to be honest [23:38] mikeal: i've done a **lot** of stuff with WSGI [23:38] hassox: but by keeping each unit of computing small, you allow other events a chance to get into the queue [23:38] mikeal: and that model just doesn't fit as well in node [23:39] hassox: you're not going to get the perverbial beachball of death in your process [23:39] felixge_: kriskowal: is there any reason you freeze everything you get your hands on in the Q module? [23:39] mikeal: you can block on processing, which is why you want to try and divide up the processing in to smaller units [23:39] kriskowal: it's future-looking. [23:39] mikeal: you hit the same problem when you want to paralleize to multi-core [23:39] johnw has joined the channel [23:40] kriskowal: felixge_ it will eventually be possible for mutually suspicious programs to run in a single event loop. the events system would be responsible for mediating interactions among those components [23:40] hassox: my twitter example does this... [23:41] hassox: it has one program reading from twitters firehose and emitting events [23:41] kriskowal: it's an object-capability programming thing. the intent is that a function can "defer", and retain for itself the sole means of resolving the promise, while giving someone else the ability to observe the fulfillment or rejection of that promise. [23:41] mikeal: this is starting to sound like erlang :) [23:41] hassox: and another program that is a http server serving those events with long open connections to clients [23:42] hassox: kriskowal: am I wrong to believe that this is not possible with jsgi? [23:42] jcrosby has joined the channel [23:42] felixge_: kriskowal: hm ... not sure if I like that approach [23:42] kriskowal: atm they're noops [23:43] kriskowal: only rhino, to my knowledge is able to freeze objects [23:43] felixge_: kriskowal: also, any reason you make OOP look so painful? [23:43] mikeal: it sounds like you're concerned about a side effect where another piece of code resolves a promise and you want assurances that only the function itself can do so in order to limit the side effects [23:43] felixge_: it seems like you want to get rid of the 'new' keyword [23:44] mikeal: but what you're opening up is the potential for more leaks if your function doesn't resolve it's promise and nobody else is allowed to [23:44] mikeal: haha [23:44] kriskowal: the "new" keyword has its places. [23:44] mikeal: i'm going to tweet that [23:44] kriskowal: as does "this" [23:45] kriskowal: just not in an ocap program [23:45] hassox: ocap? [23:45] jan____: I'd +1 a rm new. [23:45] kriskowal: object capability [23:46] hassox: jan____: why's that? [23:46] kriskowal: my personal favorite reason for not having new is that any constructor can serve as a factory method. [23:46] hassox: kriskowal: I had a discussion with halorgium last night and he made some good points [23:46] hassox: but another question I have [23:46] jan____: hassox: too close to java [23:47] hassox: is why should a middleware _have_ to pass the request through itself if it doesn't care about the response? [23:47] mikeal: most interpreters start to break badly when you recursively use new in a constructor [23:47] hassox: jan____: oh I thoguht it might be some technical reason ;) [23:47] mikeal: in Firefox this somehow turns into a pointer to the window [23:47] hassox: kriskowal: on the way out I mean [23:47] jan____: hassox: me, of course not :D [23:48] mikeal: i hate middleware, that's right! i said it! [23:48] hassox: kriskowal: also is that twitter example ^ ^ possible with jsgi? [23:48] hassox: or would it ever be? [23:49] kriskowal: the twitter example would work [23:49] jan____: mikeal: you should work for us! [23:49] mikeal: haha [23:49] kriskowal: anyhow, someone's paying me to do something else right now. ttyl [23:50] felixge_: kriskowal: ttyl [23:50] hassox: so you can hold open connections to the client and push out the events [23:50] hassox: kriskowal: kk [23:50] mikeal: it just seems like middleware, specifically wsgi middleware, can't do anything non-trivial in a way that will always interop with other middleware or wsgi applications [23:51] mikeal: it feels a lot like unittest extensions in Python, they can't be built in a way that actually interops between extensions [23:51] hassox: mikeal: middleware can be used for very good reason [23:51] mikeal: which means they are basically useless [23:51] hassox: take a router for ebg [23:51] hassox: eg [23:51] hassox: it's non-trivial [23:51] hassox: and very useful [23:51] mikeal: i think middleware is a poor standin for a real extension framework [23:52] hassox: also authentication can be implemented as middleware that is utilized downstream [23:52] mikeal: it **can** be [23:52] mikeal: but there is no guarantee that it can interop with the application layer or other middleware because it doesn't have specific extension point [23:52] mikeal: it's like the difference between the auth middelware in Python and the django authentication system [23:53] hassox: I'm not familiar with those [23:53] mikeal: with django auth you can extend it to provide all kinds of stuff and always interop with other django mods [23:53] hassox: pls esxplain [23:53] mikeal: because it's specifically engineered for extensions built around auth and users [23:53] mikeal: wsgi middleware just adds stuff to environ [23:54] mikeal: there is no specific way you're intended to consume that at the application level [23:54] mikeal: and if you say, provide a new authentication scheme like OpenID, there is no way to build a User system that leverages auth in an authentication sheme neutral way [23:55] mikeal: wsgi was specifically built as a standard to abstract applications from servers [23:55] hassox: mikeal: I wrote one for rubys rack system [23:55] hassox: that injects into env just like wsgi one [23:56] hassox: but it injects a lazy object which does have hooks for things like you talk about [23:56] hassox: just because the spec is simple doesn't prevent people from writing things that can be used [23:57] felixge has joined the channel [23:57] mikeal: that works great if everyone uses your auth system [23:57] mikeal: which may be the case [23:58] mikeal: but now if i want to write OpenID support I need to decide if I'm going to build it on your middleware extension or somebody elses [23:58] cadorn has joined the channel [23:58] hassox: yes [23:58] mikeal: i just think this kind of stuff belongs on the application side [23:58] hassox: this is tru [23:58] mikeal: on the application side of wsgi/jsgi you can build a framework with logical places for all of these extensions [23:59] mikeal: instead of shoehorning them in to server/application bridge [23:59] mikeal: people try to do it this way in the Python world mostly because there are 7 x 84323 web frameworks