2010-07-26:
[7:16] <ashb> Ruby's File.expand_path is *fruity*[7:16] <ashb> File.expand_path('../../Gemfile', __FILE__)[7:16] <ashb> gets you the Gemfile in the directory above the file, not two dirs above[13:35] <mschwartz> I started an interesting project over the weekend[13:35] <mschwartz> I call it "Silk"[13:36] <mschwartz> it is a WWW server built on top of SpiderMonkey[13:36] <Wes-> silk silk silk[13:36] <Wes-> mschwartz: what do cows drink?[13:36] <mschwartz> I ran ab against it[13:36] <mschwartz> and it's 10% faster than apache[13:36] <Wes-> mschwartz: What's your implementation like?[13:36] <mschwartz> apache is serving "It works!" flat HTML[13:36] <mschwartz> silk was running a simple JavaScript to iterate the request headers and print them[13:37] <mschwartz> it's standard prefork model[13:37] <mschwartz> there's one runtime[13:37] <mschwartz> each http child gets its own context[13:37] <Wes-> mschwartz: Interesting. So you fork the JS runtime with a traditional UNIX daemon?[13:37] <mschwartz> from the command line, you run it like this:[13:37] <mschwartz> silk [-c childcount] [-p port] JavaScript.js [optional args...][13:37] <Wes-> (why bother generating a unique cx per child? Or when you say context, do you not mean JSContext * ?)[13:38] <mschwartz> JSContext[13:38] <mschwartz> each child runs the JavaScript.js you pass in[13:38] <mschwartz> each script gets the optional args passed to it[13:38] <mschwartz> I'm not even compiling the JavaScripts yet[13:38] <mschwartz> and it's 10% faster than apache[13:39] <mschwartz> each script is passed a global.res and global.req object (similar to helma)[13:39] <mschwartz> much simpler at this point, obviously[13:39] <mschwartz> the thing is, there's no "framework" forced on you[13:40] <mschwartz> whatever you implement in your JavaScript is your framework[13:40] <mschwartz> it obviously needs some glue functionality[13:40] <mschwartz> and it should support commonjs style require() and modules[13:40] <Wes-> mschwartz: You're possibly measuing a lot of apache's page-serving overhead, multiple module processing stuff[13:40] <Wes-> (do you know how apache internals work?)[13:40] <mschwartz> I know how apache internals work[13:40] <Wes-> mschwartz: You could have require() today if you recompiled with GPSEE[13:41] <Wes-> mschwartz: FWIW - if you're pre-forking, you could save JS_NewContext() and JS_InitStandardClasses() overhead by doing them in the parent[13:41] <mschwartz> I know[13:41] <Wes-> mschwartz: You would want to create a new global object per request, though, unless you know the request is for the same client[13:41] <mschwartz> I know that, too[13:42] <mschwartz> I am thinking of switching it over to use v8 (or optionally pick one)[13:42] <mschwartz> I had a previous version of Silk that was pthreaded[13:43] <mschwartz> the entire server side (including dynamic WWW pages) were written in C++[13:43] <mschwartz> if you edited a C++ file in your DocumentRoot, it would fork GCC and compile it, dlopen() it and run it on request[13:43] <Wes-> mschwartz: Nice![13:44] <mschwartz> the thing served dynamic WWW pages in nanoseconds[13:44] <mschwartz> the pthread model was too scary for me to try it in production though[13:44] <Wes-> mschwartz: So why are you so much faster than apache? (not being smart, really curious -- I have been thinking about writing an SSJS module)[13:44] <mschwartz> It's so lightweight[13:45] <mschwartz> apache is probably doing stat() on the flat HTML file[13:45] <mschwartz> but you'd think stat() would be faster than building a context and global object[13:45] <mschwartz> on the other hand, I notice Helma 1.7.0 doing helma.File.listRecursive() can take many milliseconds for even a small directory tree[13:46] <mschwartz> I have a TServerSocket class[13:46] <mschwartz> and a TSocket class[13:46] <Wes-> stat() speed depends a LOT on the calling environment as well[13:46] <mschwartz> TServerSocket is instantiated in the parent process[13:46] <mschwartz> each child calls TSocket *s = TServerSocket.accept()[13:46] <mschwartz> (something like that)[13:47] <mschwartz> TServerSocket.accept() does flock() on the fd, then accept, then flock() to unlock it[13:48] <mschwartz> stat() is slow enough that PHP caches the stat() results[13:48] <Wes-> Interesting, running gsr against a script file vs. against a command-line script takes 0.028s vs. 0.026s. In that 0.002 I stat() and mmap()[13:48] <Wes-> This is on leopard with a ~2 GHz machine[13:49] <Wes-> I wish I could measure that a little more fine-grainily[13:49] <mschwartz> gettimeofday()[13:49] <Wes-> (truss on solaris is nice for that)[13:49] <Wes-> Yeah, I could do that I suppose :)[13:49] <mschwartz> new Date().getTime()[13:49] <mschwartz> LOL[13:50] <Wes-> Hm[13:51] <mschwartz> Silk also buffers the output to the browser (so it can calculate content-length), which may also slow it down some[13:51] <mschwartz> new Date().getTime() is only millisecond resolution[13:51] <mschwartz> but gettimeofday() is usec[13:51] <mschwartz> not guaranteed, though[13:51] <mschwartz> there's also clock()[13:53] <mschwartz> wes - why spidermonkey and not v8?[13:53] <mschwartz> (GPSEE)[13:53] <mschwartz> I chose spidermonkey in case I went pthread route, and spidermonkey has thread_safe code[13:54] <Wes-> mschwartz: Biggest reason - v8 did not exist in August 2007. Also, community involvement, feedback, advanced JS features, my confidence that the engine will continue to evolve and serve my needs over time.[13:55] <Wes-> mschwartz: Turns out ms resolution is enough to measure stat on my box, I get 21 ms for this: http://pastebin.mozilla.org/754647[13:56] <Wes-> mschwartz: I suppose it's also worth pointing out that v8 doesn't run on sparc CPUs[13:56] <Wes-> (and I use 'em all over the place)[13:56] <Wes-> And if you think v8 is fast, wait 'till you firefox 4[13:57] <ondras> also, gm supports some additional features not present in v8[13:57] <ondras> such as e4x, "const" and much more[13:57] <mschwartz> 21 ms for 1000 x stat[13:57] <ondras> (which is a pity)[13:57] <mschwartz> so 21 ns[13:57] <mschwartz> er[13:57] <Wes-> mschwartz: Yep. And that's hitting a cache in the kernel[13:57] <mschwartz> 21 usec[13:57] <mschwartz> well[13:57] <mschwartz> listRecursive() is doing readdir[13:57] <mschwartz> readdir()[13:58] <Wes-> Yeah. readdir() can be a real bitch, especially when dirs get big and holey[13:58] <Wes-> mschwartz: BTW, what do you think of my FFI syntax? :)[13:59] <mschwartz> interesting[13:59] <mschwartz> I'm getting to the point of implementing glue[14:00] <Wes-> mschwartz: What kind of glue are you looking for?[14:00] <mschwartz> I realize it's going to be a lot of copy/paste and tweak[14:00] <mschwartz> I was thinking... Posix.*() functions[14:00] <mschwartz> I might even want to implement the glue type stuff as .so files[14:01] <mschwartz> and have the server dlopen() them[14:01] <Wes-> mschwartz: FWIW - GPSEE strives to make all of POSIX (single unix 3) available via the gffi module, including structs, portably (so JS doesn't need to know layout details)[14:01] <Wes-> mschwartz: I also have commonjs require() for .so files[14:01] <mschwartz> seems like the way to go (.so)[14:01] * Wes- nods[14:02] <mschwartz> btw[14:02] <mschwartz> I think I can create the globalObject in the parent[14:02] <mschwartz> and just stuff in the req and res objects in the child over and over again[14:03] <mschwartz> not sure if the GC() overhead is worth it though[14:03] <mschwartz> I can always benchmark it[14:04] <Wes-> mschwartz: glue - http://code.google.com/p/gpsee/source/browse/modules/net/net.js - node's net API implemented in JS, calling select() about the same way as thttpd works[14:04] <Wes-> mschwartz: glue - http://code.google.com/p/gpsee/source/browse/modules/fs-base/fs-base.js - commonjs fs-base module. (note that .call() is now deprecated and un-needed)[14:05] <Wes-> mschwartz: Are you running content-generation code in your children, or just implementing HTTPd?[14:05] <mschwartz> child can do what it wants, no?[14:05] <mschwartz> child can switch on hostname and do vhost (in the JavaScript.js)[14:06] <mschwartz> the script can require() or include() other scripts to make a complex appliation[14:06] <mschwartz> application[14:06] <Wes-> mschwartz: Depends on what you want it to do. :) - reason I was suggesting fresh global was to avoid leaking data from request to another[14:06] <mschwartz> or the script can do something trivial like...[14:06] <mschwartz> check HTTP_REFERRER is me, then do res.forward() to an image file[14:07] <mschwartz> the beauty of the process model[14:07] <Wes-> If you're worried about data leakage, BTW, I have API for this which covers both JS modules and C code. (GPSEE realms) -- we needed it because of worker threads and multiple runtimes. (need multiple runtimes for the debugger, which itself is written in JS)[14:07] <mschwartz> is you can do 100 keep-alive requests, leaking memory the whole time[14:07] <mschwartz> then exit()[14:07] <Wes-> mschwartz: You are doing pre-fork but don't reuse across different connections?[14:07] <mschwartz> what do you use to talk to the debugger?[14:07] <Wes-> mschwartz: JSD[14:08] <mschwartz> reuse what?[14:08] <Wes-> mschwartz: I have a local fork of the old jsdb project, with a local JSD fork[14:08] <Wes-> mschwartz: the child[14:08] <mschwartz> oh[14:08] <mschwartz> yeah[14:08] <mschwartz> the child does:[14:08] <mschwartz> if (my_request_count > max_request_count) exit();[14:08] <mschwartz> plus keep alive[14:09] <mschwartz> so you can serve 1000 requests[14:09] <mschwartz> 30 keep-alive at a time[14:09] <mschwartz> (tunable parameters)[14:09] <Wes-> mschwartz: You can tune the GC to not hurt much in a leak,leak,leak child - there is a test and tunable which basically won't trigger GC until the heap size increases a LOT (e.g. doubles)[14:10] <mschwartz> the pthread/C++ version of silk was pretty amazing[14:10] <mschwartz> it had several caches[14:10] <mschwartz> one for static objects[14:10] <mschwartz> one for dynamic objects[14:10] <mschwartz> so serving an image (or other static file) was done from shared memory almost all the time[14:11] <mschwartz> mmap() rocks[14:11] <mschwartz> for doing that sort of thing with processes[14:12] <Wes-> Yep, it's absolutely perfect. A little trickier with the pre-fork model, would be interesting to have a pipe back to the parent, feeding it filenames to map for future children[14:12] <Wes-> Although, there's one other API to consider, what the heck is it... It's the one that allows you to spool right from disk controller to network card[14:12] <Wes-> I guess that's probably only realistic for large files any how[14:12] <mschwartz> there's another one, too[14:13] <mschwartz> I think apache uses it to bypass socket writes[14:13] <Wes-> Ah - I'm thinking of sendfile()[14:13] <Wes-> Maybe what you're thinking of, too?[14:13] <mschwartz> maybe[14:14] <Wes-> I know there is an APR version of it[14:14] <Wes-> mschwartz: Is your work on silk foss?[14:15] <mschwartz> nope[14:15] <Wes-> mschwartz: Bummer, it sounds cool.[14:15] <mschwartz> oh[14:15] <mschwartz> I just haven't decided what to do with it yet[14:15] <mschwartz> it will most likely be open source[14:15] <Wes-> mschwartz: If you want to try a GPSEE underpinning - let me know, I can still help (was hoping to just do a port for you :) )[14:16] <mschwartz> you guys like github...[14:16] <mschwartz> LOL[14:16] <Wes-> Actually, I prefer google code.. but any DAG VCS is fine by me[14:17] <mschwartz> man 2 splice[14:17] * Wes- has considered buying the license plate DAG BTW[14:17] <mschwartz> hah[14:17] <mschwartz> I tell you what[14:17] <mschwartz> I'll put it on github tonight[14:17] <Wes-> mschwartz: Is that anything like weave? I don't have splice on either leopard or solaris[14:17] * Wes- dances[14:18] <mschwartz> I want to set up a real message board for discussion though[14:18] <Wes-> mschwartz: I'll fork it and make it build on GPSEE tonight if i have the chance. Might be useful, would at least be a fun thing to play with[14:18] <mschwartz> I HATE google groups[14:18] <mschwartz> I don't mind if you commit to the main fork[14:18] <Wes-> mschwartz: I do too, but I like out sourcing[14:18] <mschwartz> I have the server to set up a real message board[14:18] <Wes-> mschwartz: We'll see how much surgery is involved. Hopefully, very little.[14:19] <mschwartz> one where you can put source code in a post[14:19] <mschwartz> and it syntax highlights[14:19] <mschwartz> track bugs[14:19] <mschwartz> post attachments[14:19] <Wes-> mschwartz: I have servers galore, but, seemingly no time at all. Project Kenai looked like it was going in an awesome direction (mercurial, bugzilla, forums) - but then they locked me out of my account and then oracle killed it[14:19] * Wes- sighs[14:20] <mschwartz> there is one other thing I'm tempted to do with silk[14:20] <mschwartz> that is to embed PHP as well[14:20] <Wes-> mschwartz: There is a spidermonkey project somewhere that lets jsapi and php interoperate[14:20] <mschwartz> so a single Silk server could run WordPress and custom JS app at the same time[14:20] <Wes-> mschwartz: he does it by translating at the jsval / zval level - even function calls work[14:20] <mschwartz> oh[14:21] <mschwartz> I don't want to mix the code[14:21] <Wes-> I wish I could remember the name of that project[14:21] <mschwartz> just to be able to run out of the box PHP apps[14:21] <Wes-> mschwartz: c'mon, be brave! :D[14:21] <Wes-> mschwartz: But I hear you. That's why I've been looking at doing a GPSEE Apache Module[14:21] <Wes-> mschwartz: Currently, I haven't figured out /what/ I'm doing for web work; I run CGI for God's sake, although I'm working on a Solaris port of APE to play with[14:22] <mschwartz> ouch[14:22] <mschwartz> those SPARC chips make porting code a problem these days[14:22] <Wes-> Yeah, good thing I don't need any volume (10 requests/sec is PLENTY and I can do that easily)[14:22] <mschwartz> I am always searching for the microsecond speed server side script[14:23] <Wes-> mschwartz: This isn't a sparc problem so much as a solaris/kqueue/epoll/etc problem. Author wrote bare-metal code for Leopard and Linux[14:23] <mschwartz> my view of the future of WWW is you serve a WWW page that's simple[14:23] <mschwartz> it has JS on it[14:23] <mschwartz> the JS does a bazillion RPC like requests[14:23] <Wes-> mschwartz: That's similar to the APE model[18:34] <WesMac> anybody on Snow Leopard willing to help me test the GPSEE build system?
Logs by date :