And by we, I mean myself, parrot, and mod_parrot. That is simple: cgi-style running LIVES AGAIN (almost, just need to fix headers ;-)). And with it, all the infrasturcture to implement more and nicer loaders, such as those for PSGI and / or WSGI, and the famous inline loader-in-the-sky I will be writing. Pretty nice, no?
For the technically interested, what has happened is that:
- Loaders now accept 3 arguments: the request (as a PtrBuf). This is an opaque handle, that can be used to bind to the apache input / output handles.
- The aforementioned io handles are now pre-loaded into parrot. Infrastructure is in place to load more, but I do not yet see a purpose for this. They are, however, not setup initally. This is to simplify writing PSGI and similar loaders, which may assume that standard output is NOT send to the server. apache.setup(request) is available to bind apache handles to standard handles.
- By the way, call apache.setup() only once, PLEASE. Do otherwise and cause a crash. This should be fixed - a singleton instance? - but isn't, now.
- The language for the script is stored in a hash (this was already the case) but is now also pre-loaded via Parrot_api_load_language. Whether this does any good I do not know, but it was simple so I added it.
- Utilities have finally been moved to the mod_parrot_util.c file, which reduces duplication somewhat.
- Oh yes, header output and input now just works. I also moved the cgi-ification (uppercasing, transliterating non-alphanumeric charachters to underscores) from the C-layer to the winxed layer. It was simple in C, but it is simpler in winxed, and moreover it is probably more unicode-compliant.
- And finally, I 'un-OO-ed' puddings Client.pm package, meaning that the server of-which-we-are-a-client is now a package global, and that what used to be a method is now just a sub. Thus, $client->content() now just looks like content(). Which would be nasty if Client wasn't designed to be used as a testing system. My mind may change on this however.
There where also some troubles. Those who listen in on irc (or read the logs) might have heard me complaining about voodoo. Specifically:
- I have had the largest possible problem passing a parameter called 'request' to the echo loader. This request turned out to be a NullPMC, whose get_pointer() calls NULL, which is passed to the C layer as NULL, and which causes a segmentation violation, or segfault. GDB showed me this in minutes, but not /why/ it was NULL. After all, passing the same parameter to a different routine worked splendidly. After a few hours, I figured out that there was a post-declaration of 'var request' that overrides the one passed to the function. Note to the implementors of winxed: warning for this is more usefull than warning for class names that 'do not exist' :-).
- I have attempted fruitlessly to make adding library directories (and with that, loader directories) more flexible by using an array. Currently, we have the option ParrotLoaderPath, I wanted to change that to ParrotAddPath (and push to an array). Apache comes with the apr_array_header_t array type, which works splendidly for this purpose. However, after the first request, the array that used to hold two elements now holds just one? It is honestly beyond me why, but it might have something to do with pooling.
- And why, why, why does mod_parrot cause the server to shut down (exit code 1) where there is an unhandled exception in my one-level-deep function? A segfault or SIGABRT would be more useful, people, at least then I'd have gdb to help me out. A try/catch block solves my problems, but is undescribably nasty.
What I really want to do next is
- Communicate a status code to the web server. You know, like '200 OK', '404 Not Found', '500 Internal Server Error'. Simple, low-hanging fruit, but important nevertheless.
- Create more (far more) loaders. Different loaders are cool, they go beyond what other modules can easily do, they give webmasters incredible flexibility.
- resilient (server-thread-local) parrot instances. Currently, I create a new interpreter per-request. This is elegant enough, but not very fast. mod_parrot should be awesome, and nothing is more awesome than speed. More to the point, I believe it can actually be done.