
via www.flickr.com
Yeah, the new theme rocks.
The banner photo was taken in Koh Samui in 2006 with my pretty old Canon point-and-shoot camera. The photo is obviously retouched a little bit with Picasa to look better, though :)
via www.flickr.com
Yeah, the new theme rocks.
The banner photo was taken in Koh Samui in 2006 with my pretty old Canon point-and-shoot camera. The photo is obviously retouched a little bit with Picasa to look better, though :)
I've been always having problems locating the right POD files when I deal with a big module/software/framework in Perl, for instance, Moose. They have a fairly good amount of document, but merely doing `perldoc Moose` doesn't give me what I want to know: I usually need to do `perldoc Moose::Manual` and then `perldoc Moose::Cookbook` to scan for the things by typing i want to know. It's tedious.
perldoc-search is awesome: it gives you an ability to search your local POD files without building index like Spotlight. For instance, when I need to know how to mangle new() args in Moose, i can just type: `perldoc-search BUILDARGS -G Moose` (-G is a regular expression to match filenames to look for) and it gives you a fairly small amount of files, including Moose::Cookbook::Basics::Recipe10 which exactly tells me what I need to know.
install App::Perldoc::Search now and enjoy.
We've been using #http-engine IRC channel for the convenience but we agree that PSGI/Plack talk invades the whole channel and is confusing to newcomers: so we made a new IRC channel dedicated for PSGI and plack talk (yes, another channel!)
Try::Tiny rocks.
Every perl programmer should start using it. Especially if you're a CPAN module author and wants to eval { } inside your module (often to check if an user of your module has some optional module installed, in which case you optimize stuff for it etc.), you're strongly suggested to use this module instead of your own eval { } stuff.
Why? If you do eval { } in your module that clobbers the global [email protected], and to avoid that you need to local [email protected], and then if you want to die (rethrow) from local [email protected] then the exception gets cleared etc... Try::Tiny solves this endless yak shaving and there're no dependencies at all and works with perl back to 5.005x.
Anyway, i started using Try::Tiny (when nothingmuch himself added this :)) in Plack and Tatsumaki with so much fun, but last night I experienced one minor pitfall of this module that I might want to share with you.
I had this code:
sub write {
my $self = shift;
my $writer = $self->writer || $self->init_writer;
$writer->write(@_);
}
I wanted to catch Broken pipe exception from ->write, so I changed to do this:
sub write {
my $self = shift;
my $writer = $self->writer || $self->init_writer;
try {
$writer->write(@_);
} catch {
/Broken pipe/ and $self->{client_disconnected} = 1;
};
}
It might be obvious to you but for me it wasn't at first, and I wasted about 15 minutes to figure out what's wrong with that code.
Yeah, the use of @_ in the try { } clause. it's internally implemented as try sub { ... } so the content of @_ is changed when it's executed.
Lots of clever modules on CPAN that exports DSL sugars (including my own Web::Scraper) shares the same problem. At least you have to be careful not to use @_ in the block, by assigning the @_ content into some lexical variables before you construct the block,
(Well maybe Try::Tiny can add a workaround to save the @_ in the caller stack but i'm not sure if it's a doable without black magic like DB::args and whether it's right thing to do anyway)
Anyways, Try::Tiny is a great module if you care about this tiny thing. Enjoy.
UPDATE: this is now mentioned in Try::Tiny POD docs.
cpanf Task::Plack
(install App::CPAN::Fresh if you haven't :)) and now you can call perl -MTask::Plack -e git_clone
on your shell, which clones all Plack/PSGI relevant development git repositories for you. This is quite handy now that we split the Plack repo into multiple projects.
Kazuho made mod_reproxy for Apache2 and typester made one for lighttpd.
They add a support for X-Reproxy-URL header, which is used in perlbal often in combination with mogilefs, so your web app can internally redirect static files to other static web server after the authentication etc. is done. It's more flexible than X-Sendfile since the file doesn't really have to live on the frontend proxy, which is not often the case in the user uploaded content like photos or videos.
Good stuff.
In the last couple of (or even more :) days Yuval and I have been endlessly discussing what the asynchronous response API would look like in PSGI applications. And that was also becoming one of the most frequently asked questions on my side, since many people from AnyEvent, POE and perlbal (Danga::Socket) land are curious how to port their non-blocking application to let them run on PSGI servers.
Thursday while having frodwith on board in the discussion (that was really helpful since he has a third person view as a POE developer) and we sorted out the nicely done middle ground, which is actually the revive of our original start_response callback we abandoned in favor of IO::Writer-like abstraction.
So, basically the idea is the same as the original Python WSGI's start_response but this callback is NOT an optional parameter to the app because that stands in the way of everybody in the chain including middleware and that sucks. Instead, an app can optionally return a callback that accepts another callback to which you can return the response array ref (code, headers and body) if you want to delay your response.
my $app = sub { my $env = shift; return sub { my $respond = shift; # do some event stuff $event->callback(sub { $respod->([ $code, $headers, $body ]) }); }; };
If you also want to delay the content body delivery as well (i.e. streaming) you can omit the body, in which case you'll get the writer object that has write(), close() and poll_cb().
my $app = sub { my $env = shift; return sub { my $respond = shift; my $w = $respond->([ 200, [ 'Content-Type' => 'text/plain' ]]); # no $body here # do more event stuff $event->callback(sub { $w->write($body) }); $event->done_callback(sub { $w->close }); }; };
I plan to update the PSGI specification to address this optional response style in a few days. Yuval also has a nicely summarized blog post on this, and we already added this callback style to our AnyEvent, Danga::Socket, Coro and POE backend as well as most middlewares, including automatic chunking middleware (supposedly used by servers, not apps) which I line-by-line cloned from Rack :)
Meanwhile Yuval is working on his data-pimping REST machine Hydrant and I've been working on Real-Time-optimized web framework Tatsumaki, and both will be built on top of PSGI/Plack from the ground up. This will definitely be how web frameworks in Perl would look like in 2010.
Friday night I was at my friend's party and five people talked to me how awesome Plack is and it's changing the world. (Disclosure: it was a party full of my Six Apart co-workers and alumni like Artur, Randy and Simon, so that's not that surprising :))
Some yak have been shaved and the last minute bikeshed of renaming things in Plack::Builder was done, and now Plack and PSGI are uploaded to CPAN!
Some server backends like AnyEvent, FCGI::EV, Coro, Danga::Socket, ReverseHTTP and ServerSimple are removed from the core distribution and uploaded to CPAN separately. Actually there's no reason those implementations need to be named Plack::Server::* anymore since it doesn't inherit anything. I have more to write about naming your stuff on CPAN, hopefully soon to be posted here.
I also uploaded Catalyst::Engine::PSGI but i keep other framework adapters like Maypole, Mason, Mojo, CGI::Application and Squatting in my github repos for now, since some of the implementations are pretty hacky, and I'm not confident nor comfortable maintaining those adapters when bugs are found etc. Anyone from the dev team of these frameworks want to take care of actually releasing this to CPAN or porting to the core? :)
Anyway, this is a big milestone. Thanks everybody for helping me this past month and let's celebrate the initial release, but let's continue hacking!
The idea goes like this: Web applications, when all is said and done, are really just on about sending three pieces of information to web browsers: a HTTP status code, a list of HTTP headers, and some content (a file or some text, normally HTML).
via blog.patspam.com
Patrick from WebGUI has posted a wonderful introductory article on PSGI and Plack, and he actually shows his working code to run WebGUI framework on top of Plack stack. This is way too awesome to believe.
via www.flickr.com
I combined all of the great works done by tokuhirom, kazuho, nipotan and Sartak: render Devel::StackTrace object as an HTML. As a bonus, if you render WithLexicals object it will display the lexical variables with JS toggle button.
Plack middleware and plackup has now been converted to use this new StackTrace screen. Pretty slick!
The Osaka High Court on Thursday acquitted the developer of the Winny file-sharing software program of copyright violation, reversing the initial guilty ruling by a lower court that imposed a 1.5 million yen fine.
via home.kyodo.co.jp
Big congrats to my friend software developers in Japan. Justice is done and the developer behind Winny, peer-to-peer file sharing software is judged innocent.
View more presentations from Tatsuhiko Miyagawa.
Today I did a presentation about PSGI and Plack for Six Apart engineering team including our Python dev team and MT service developers from our New York office.
The presentation got well received and some demonstrations like StackTrace, ReverseHTTP and NYTProf (which I started working on last night, will commit to the git repo later) really wow'ed them.
I'm happy to give this talk in other external meetings or conferences, like SF.pm meetup. Stay tuned :)
via www.amazon.co.jp
This book seems really interesting: titled "English sentences Japanese people will always misinterpret". It seems like the collection of English phrases and sentences often confusing to non-native speakers, especially Japanese.
The fact it's more interesting, or rather funny, is that this book is written by Toshiya Echizen, who is known as an English literature translator for books like Da Vinci Code or Angels and Demons.
Yeah, I guess there are many sentences by Dan Brown which anybody will never understand: )
I've got a comment about "What about Mojo?" on my yesterday's blog post, and I answered Mojo is something different that implements everything from the ground up, but it was actually easy to write a Mojo adapter for PSGI by mimicking their CGI adapter. So here you go: Mojo::Server::PSGI.
mst looked at my blog post and FAQ and whined that being unable to distinguish /foo/bar from /foo%2fbar just breaks the whole Catalyst, which is actually true (and that's why their CGI engine is broken). We talked about it for an hour and agreed to include REQUEST_URI, the undecoded raw URI (required) in the $env hash.
I understand that it's kind of orthogonal and inconsistent to incldue REQUEST_URI rather than RAW_SCRIPT_NAME and RAW_PATH_INFO, but here's why: some environments, like CGI adapters, can't really tell RAW_* because they're already decoded by servers. To (unreliably) get those values you should estimate and reconstruct from REQUEST_URI. That means if you have REQUEST_URI (the unparsed full URI including query strings if any) then you can programatically construct undecoded version of SCRIPT_NAME and PATH_INFO really easily. And REQUEST_URI is, even though it's not speced in RFC 3875, set almost everywhere in CGI/FastCGI server implementations.
mst and I agreed that Catalyst and most frameworks that want full control over URI mapping would be fine with this REQUEST_URI addition. I updated the test case and included support for REQUEST_URI in all Plack servers, with the help of kazuho's HTTP::Parser::XS update.
We'll need to provide a nice wrapper methods on Plack::Request so the users can get the "base path" (the application base hosted path) and normalized URI etc. Currently you can get the raw URI (path + query) with $req->request_uri and normalized URI with $req->uri but to me they're just confusing. I'll redo and rename those methods to be more useful. Any suggestions on that would be welcome.
In #london.pm IRC channel last night I also got some chat with lathos (Simon Cozens) and konobi, where they ask me some interesting questions, especially since lathos is a happy user of HTTP::Engine and he wondered what are the actual benefits of switching from HTTP::Engine to PSGI/Plack stack.
Based on the chat with lathos, konobi and mst I updated the FAQ to include those questions and answers. This makes an awesome FAQ list. If you have more questions that are not answered, don't hesitate to ask on comments or on IRC channel #http-engine on irc.perl.org.
Our Plack/PSGI website is up at plackperl.org. Yeah, read it like "Black Pearl" :)
Couple of people have shown interest to Plack and wondered ways to extend PSGI applications or Plack servers by patching them. No, most of the time you don't need to, and you can just write middlewares.
So here are some sample Middlewares: RearrangeHeaders that sorts HTTP headers based on "Good Practice" from 199x, SimpleContentFilter that applies regular expression based filters to response body, and RequestResponseWrapper that passes Plack::Request and expects Plack::Response, much like HTTP::Engine.
Pretty powerful.
Note that this RequestResponseWrapper would lose your "application" compatibility with PSGI though. Your app that takes $req and returns $res is not "PSGI app" anymore. It'd be much simpler you do Plack::Request->new(shift) and then returns $res->finalize in your app and that's still PSGI compatible. Take the wrapper as a sample anyway.
On my way home I was thinking which frameworks should be added to the "Supported frameworks" list on our site to be more exciting. I felt a little old but thought of the two big names from pre-Catalyst era, like 2002-4. Mason and Maypole.
So there you go: HTML::Mason::PSGIHandler and Maypole::PSGI. Both uses CGI::PSGI for the easy migration from their CGI equivalent (HTML::Mason::CGIHandler and CGI::Maypole).
Maypole was a little hard to adapt since their list of dispatchers is hardcoded and uses multiple inheritance (injecting @ISA at runtime ... yeah, like old Catalyst) and you can see my semi-rants in the source code, but overall it works pretty nice.
So who's next? Do you have a web framework that can be added to the list?
Recent Comments