>From the docs: > You must call clean_request_args() on the ApacheHandler object at the end of > the request, unless you are making a new ApacheHandler object for every > request. Otherwise bad things will happen. > > This is lame, so if someone thinks of a better way to do this, I'd be happy to > hear about it.
In my massively more complicated (in both the good and bad senses of the word), but spiritually similar Mason-using WebApp framework, I do something like this: --- <LocationMatch "^/foo/bar"> PerlSetVar WebAppClass "WebApp::Foo::Bar" SetHandler perl-script PerlHandler Apache::WebApp </LocationMatch> --- # Apache/WebApp.pm our(%Apps, $Interp); # caches sub handler($$) { my($self, $r) = @_; $self = $self->new($r) unless(ref $self); $self->sanity_check() or return $self->status; my $app = $self->app; $self->parse_query($r, $app) or return $self->status; return $self->handle_request($r, $app); } ... # "app" is a "get, set, init" attribute (c.f. Class::MethodMaker) sub init_app { my($self) = shift; my $r = $self->apache_request; my $class = $r->dir_config('WebAppClass') or die "No WebAppClass defined for this location: ", $r->uri; if($r->dir_config('WebAppNoAppCache')) { return $class->new(); } else { return $Apps{$class} ||= $class->new(); } } sub init_mason_interp { $Interp ||= ... } # more "get, set, init" sub handle_request { my($self, $r, $app) = @_; $app->refresh(); $app->params($self->params); $app->mason_interp($self->mason_interp); $app->run(); my $status = $app->status; $app->clear(); return $status; } --- # WebApp/Foo/Bar.pm package WebApp::Foo::Bar; use strict; use WebApp; our @ISA = qw(WebApp); sub root_uri { '/foo/bar' } # duplicated, but oh well ... --- Basically, I try to separate the thing that dispatches incoming requests (Apache::WebApp) and the things that are dispatched to (the actual apps, e.g. WebApp::Foo::Bar) Every <Location*> directive has the same PerlHandler (Apache::WebApp) but different WebAppClass settings. Of course, I'm free to subclass any of these classes to make some sort of specialized behavior, but so far, the basic "dumb caching" dispatcher (Apache::WebApp) has done everything I need. But getting back to the point of this post, Apache::WebApp is where I do all the per-request setup and cleanup, not in the apps themselves. That way, writing a WebApp doesn't involve worrying about any of the boring setup and cleanup stuff that every app needs to do in order to work correctly (e.g. Not have any stale data left over) Session cleanup/save-back can be done either in the Apache::WebApp dispatcher or at the end of the app objects' run() method. In practice, I do it in the dispatcher and also in some apps, using a save_if_modified() method which is inexpensive enough that I don't care about duplicated calls. You'll also notice that I do a "$app->refresh" before and a "$app->clear" after processing a request in the dispatcher. This is because some apps may choose to "empty" themselves when not in use, even if they app object is still cached in %apps. So "clear()" would really clean out all data structures, while "refresh" would rebuild them before the next run. -John -- Report problems: http://perl.apache.org/bugs/ Mail list info: http://perl.apache.org/maillist/modperl.html List etiquette: http://perl.apache.org/maillist/email-etiquette.html