Re: a better way to recognize module changes
On 9/11/09 6:57 PM, Jonathan Swartz wrote: PerlSetVar ReloadAll On PerlSetVar ReloadHttpds My::Moose So that modules in ReloadHttpds terminates existing user httpd processes and causes the server to fork off new httpd children. But again, if Apache::Reload runs as part of the child process itself, how can it implement ReloadHttpds effectively? It would have to kill itself off, which would mean your first request would generate an error - not a good user experience. The last thing I did in this area looked something like this: PerlCleanupHandler My::WebApp::Restarter PerlSetVar WatcherInterval 60 PerlSetVar WatcherCompileCheck 1 where all the handler did was fork off a watcher process if one didn't already exist. The watcher would then stat() all the files in %INC periodically. If one had changed, it'd attempt to compile it (if WatcherCompileCheck was true) catching/absorbing any errors to prevent ugly output, and then restart the apache server by sending it a signal if the file compiled okay. Doing a full restart avoids all the odd module re-load issues (and there are many). The polling interval may seem too long, but this would all happen as you were working on the code and before you reached back to a browser window to reload a page. By the time you did, the hope was that the server would already be back up again. One obvious improvement would be to use kqueue/inotify/FSEvents to avoid polling entirely, making it much more likely that the server would be back in time for your next request. -John
Re: mod_perl survey results
On Tue, Nov 11, 2008 at 1:27 PM, David E. Wheeler [EMAIL PROTECTED] wrote: On Nov 11, 2008, at 10:15 AM, Perrin Harkins wrote: I'm fine with people using other open source tools to get where they want to go but the justifications they make about mod_perl being heavier or slower rarely have any actual research behind them. Yeah, I wasn't making the case for mongrel or lighthttpd myself. I still prefer mod_perl. But that argument is out there. Hmm, this is making me want to run benchmarks! Maybe a solid set of benchmarks would be a fun OSCON presentation next year. Great idea. What benchmarks won't show is the weird issues Young New Server X will have on Esoteric Platform Y and all the other real-world pitfalls that the long-time players in the web server field have dealt with and worked around over the years (...where Esoteric may actually be any platform other than the three versions of Linux distro ABC that the developers tested it on.) (Yeah, forking, threads, sockets, shared memory, logging, etc. is old world tech and seems like a solved problem, but there are many devils in those details, IME.) -John
Re: mod_perl survey results
On Tue, Nov 11, 2008 at 1:15 PM, Perrin Harkins [EMAIL PROTECTED] wrote: On Tue, Nov 11, 2008 at 12:49 PM, David E. Wheeler [EMAIL PROTECTED] wrote: To a certain degree, Apache/mod_perl is a victim of the success of HTTP. It's fairly easy to implement a new HTTP server, so there are a lot of them, and many are easy to use and extremely fast. If all you're interested in is serving a Rails or Catalyst app, Apache/mod_perl starts to seem like much too big a beast. I've said this before, but I think this is not a very rational claim. Network servers are actually pretty hard to get right and HTTP is no longer very simple. Exactly. Anyone trying to make their own HTTP server will simply end up re-treading the same path that apache has already traveled--with all the pitfalls that entails. HTTP serving, process management, etc. is not the core function of most apps. The OSS way is to build on the work of others. Apache is and has been solving the HTTP/server problem for many years. Choosing not to stand on the shoulders of that giant should be done only with a very good reason. And sometimes there are good reasons. But what I tend to see just as often are fads and other herd behavior (e.g., the long (ongoing) trail of HTTP server/interfaces used with Rails). -John
Run code just before the original apache process forks
Is there some hook or other way to run some Perl code just before the very first fork() of the original apache process? The manual way is to put the code at the very end of the last Perl file evaluated during server start-up, but I'm looking for some way that I can do that on behalf of the user from within a module that is loaded at some point during startup. (This is mod_perl 1.x.) Any ideas? -John
Re: Perl 5.10
On 12/21/07 2:32 AM, Andreas J. Koenig wrote: I fear I do not understand enough of mod_perl to volunteer to make a release. Me neither, but have you at least contacted the mod_perl maintainers about this? Perhaps you could file a bug on rt.cpan.org even? -John
Re: Rose::DB and Apache::DBI
On 10/23/07, Arshavir Grigorian [EMAIL PROTECTED] wrote: I just started using Rose::DB and have been experiencing certain database connectivity issues. DBD::Pg::st execute failed: ERROR: prepared statement dbdpg_1 already exists A quick google turned up this page which offers a possible work-around: http://people.planetpostgresql.org/greg/index.php?/archives/110-Using-DBDPg-with-pg_bouncer.html Still, I think you should investigate until you find the actual problem. I've used RDBO wit DBD::Pg and Apache::DBI in the past and haven't encountered this problem. Also, in my main handler, I do $r-pnotes(dbh = MSS::DB-new-dbh ); I've had some bad experiences with passing database handles around in pnotes. You might want to try temporarily replacing that with with a global variable or something similarly tame just to see if it fixes the problem. Finally, I'll offer the init_db() implementation that I'm currently using with Apache::DBI. I don't think it will help your problem, but then I don't really know what's causing it. I suggest adding some debugging code until you completely understand the lifecycle of database handles in your particular application. Solutions to problems like these usually presents themselves clearly once you see when and where database handles are created, cached, reset, and destroyed. -John --- # An init_db() method for use with Apache::DBI package My::DB; use base 'Rose::DB'; package My::DB::Object; use base 'Rose::DB::Object'; ... BEGIN: { # Under mod_perl, cache the My::DB object, while letting Apache::DBI cache # the DBI $dbh it contains. Preventing new My::DB objects from being # created then also prevents DBI-connect() from being called; though it # does not always cause a literal connect under Apache::DBI, it *does* # cause Apache::DBI to reset the $dbh to its initial state (arguably an # unwanted feature under mod_perl) and this will hose any extant # transactions on that handle if the initial state is AutoCommit = 1. if($ENV{'MOD_PERL'}) { our $DB; *init_db = sub { # Can't cache in the parent apache process if($Apache::Server::Starting) { return My::DB-new; } else { if($DB) { $DB-dbh(undef); # will auto-reconnect as needed return $DB; } else { return $DB = My::DB-new; } } }; } else # act normally when not under mod_perl { *init_db = sub { My::DB-new }; }
Re: Rose::DB and Apache::DBI
On 10/23/07 5:17 PM, Perrin Harkins wrote: On 10/23/07, John Siracusa [EMAIL PROTECTED] wrote: I've had some bad experiences with passing database handles around in pnotes. It should be safe to do that. One thing to remember is that pnotes takes an alias to what you pass in, not a copy. If you feed it $foo and then change the value of $foo, the value in pnotes changes too. My problems were more along the lines of not realizing that an internal subrequest was happening, which (if memory serves) would end up clearing pnotes (or maybe my code was clearing/resetting pnotes when re-traversed for the subrequest). This was years ago, so maybe pnotes is better behaved these days, but I've still tended to avoid that feature of MP1. -John
Re: Rose::DB and Apache::DBI
On 10/23/07 6:42 PM, Arshavir Grigorian wrote: Does Rose::DB bypass Apache::DBI if connect_on_init() hasn't been called? Rose::DB just calls DBI in a straightforward manner. It doesn't do anything fancy. (Also, it's surprisingly hard to bypass Apache::DBI; it's not something that will happen by accident :) -John
Any way for a PerlHandler to know what Location block it's in?
Confusing subject, simple question: Location /foo/bar PerlSetVar MyRoot /foo/bar SetHandler perl-script PerlHandler MyModule /Location MyModule calls $r-dir_config('MyRoot') to get the /foo/bar path. I want to ditch the PerlSetVar MyRoot line because it will always have the same value as the Location directiv above it. Is there a way MyModule can get /foo/bar using some other means? (This is mod_perl 1, BTW) -John
Re: Any way for a PerlHandler to know what Location block it's in?
On 6/8/05, Geoffrey Young [EMAIL PROTECTED] wrote: $r-location() ? Duh, I'm an idiot. Thanks :) -John
Re: Any way for a PerlHandler to know what Location block it's in?
On 6/8/05, Dorian Taylor [EMAIL PROTECTED] wrote: $r-location will also return whatever's in a LocationMatch, Directory and DirectoryMatch directive, should the scope of the request lay in one of those. if you're simply clipping the location off the front of the request uri you could potentially run into trouble. you can always piggyback the Location directive specifically, using the configuration api and use what you get back from that. Thanks. I realize that, but I only need it to work specifically for plain old Location blocks. I have sanity checks to make sure it really is a prefix of the requested URI since I am indeed clipping it off the URI. None of these paths have any representation in the file system, so path_info is no help. I thought about wandering the apache config using perl's interface to that info but it seemed like too much trouble. Is there a better way to get the rest of the URI? -John
Re: [WISH] A Perlish way to detect mod_perl major version (= not $ENV{MOD_PERL})
On Thu, 17 Mar 2005 17:39:21, Dominique Quatravaux [EMAIL PROTECTED] wrote: For the record I use the following dubious hack as an interim measure: sub modperl_major_version { ~use DynaLoader (); ~return 1 if DynaLoader::dl_find_symbol_anywhere(XS_Apache_define); ~return 2 if DynaLoader::dl_find_symbol_anywhere(XS_ModPerl__Util_exit); ~return undef; } I have a function with almost exactly the same name, but I'm stripping the version out of the environment variable. I'd also like to see a cleaner way to do this. The DynaLoader method is not particularly reassuring... :) -John
Re: [WISH] A Perlish way to detect mod_perl major version (= not $ENV{MOD_PERL})
On Thu, 17 Mar 2005 14:57:24, Geoffrey Young [EMAIL PROTECTED] wrote: just added to svn is $ENV{MOD_PERL_API_VERSION}, which is currently just 2. Cool. what exactly is the issue you guys are trying to work around? I'm writing code that's intended to work under both MP1 and MP2. To split off into the right module or section of code, I ask things like, Am I running in a mod_perl environment? and Am I in mod_perl 1 or 2? I'm not sure I understand the problems with using an environment variable for this, but I'd be happy to see something better. I'm basically just looking for officially blessed, canonical ways to ask those questions. Looking at $ENV{'MOD_PERL'} is mostly fine with me, but it does bother me that I have to strip out the version using a regex and then compare it to 1.99. (What if the format of that string changes someday?) $ENV{'MOD_PERL_API_VERSION'} will help there, I think. -John
Re: [summary] The Conflict of mp1 vs mp2 vs mp22 vs ... vs mpNN
I'm going to chime in, as someone working on a suite of modules that are intended to eventually work with apache 1.x and 2.x. First, I agree with this: On 12/31/04 2:27 PM, Adam Kennedy wrote: For the moment, I'm asking just that the release of mod_perl 2.0 be put on hold until this problem, and it is most definitely a show-stopper of a problem, is resolved in it's entirety. And to the satisfaction of both the mod_perl developers and the perl community. Next, I'm going to put in my vote for a new namespace, be it Apache2:: or something else. As has been pointed out, the APIs of mod_perl 1 and 2 really aren't compatible--nor should they be. Apache 2 (the http server) took the 2.x change as an opportunity to Do It Better, and so should (and has, for the most part) mod_perl 2. Even as someone writing several modules that will need to work with both versions of mod_perl, I'd still rather have a clean split. I can abstract things easier (based on $ENV{'MOD_PERL'} most likely, but many mechanisms are possible) if there's a clean namespace split. Let me unify my API. I'll hide the Apache:: and Apache2:: (or whatever) differences behind the scenes. As for third party Apache:: modules, let them eat port. I'd rather see them make Apache2:: ports that take full advantages of the brave new world of MP2. And I'm sure many (most?) authors would like a chance to revisit their APIs anyway. Porting while maintaining API compatibility and staying in the same namespace seems like work to me. Porting to Apache2:: and being able to clean up the sins of the past and do cool new stuff in the process seems like fun. Call me crazy, but I think this is a common view among programmers (in the case of 3rd party Apache:: modules, whether they're the original authors or not). Finally, I don't see a proliferation of Apache2_2::, Apache3::, etc. namespaces as a real threat. The policy is simple: CPAN namespace == an API. If apache/httpd 2.[2-9] or 3.x requires or would benefit from a new mod_perl *API*, guess what, then you get to pick a new CPAN namespace. If not, you can continue to use Apache2:: (or whatever) regardless of how apache/httpd server changes behind the scenes. This line of thinking eventually leads to another simplifying decision: the mod_perl API versioning and branding should be divorced from Apache Foundation branding and versioning where possible. If Apache 3.x doesn't warrant mod_perl API changes, then there's no reason the Apache2:: namespace can't serve it. Ah yes, but the Apache name is in both places, so that argues for maybe ModPerl::, ModPerl2:: or MP2:: or whatever instead of Apache.*::. My summary: 1. Hold off on the offical release of mod_perl 2 until this is settled. 2. I think the simplest solution is also the cleanest and the most forward-thinking, even if it is more work: a new CPAN namespace for mod_perl 2, and a divorce of mod_perl branding and versioning from the Apache Foundation's branding and versioning. -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
Best way to distinguish between mod_perl 1 and 2
I'm looking for the best, most reliable way to determine if I'm running under mod_perl 1 or 2, or not under mod_perl at all. I suppose I can look at $ENV{'MOD_PERL'}, but that reminds me a bit too much of a user-agent style opaque string that I may not be able to trust or predict. Also, what if I see mod_perl/1.99 in that string? It just seems odd. So, any other suggestions? This needs to be code I can run even outside any mod_perl environment. I'll wrap it in an eval if I have to, but the low overhead of looking at $ENV{'MOD_PERL'} is kind of attractive... -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
Re: [PATCH] Apache::DBI support for subclassed DBI connections
On Fri, 13 Aug 2004 22:48:30 -0400, John Siracusa wrote: On 8/13/04 5:43 PM, Perrin Harkins wrote: This patch should make Apache::DBI work with subclassed DBI connections. The only downside is that it makes ALL of your cached connections subclassed if you give it one that is subclassed. Given how most people use DBI subclasses (for universal functionality on all DBI connections), this is probably not an issue. Cool, I'll try it out on Monday. If it works, you should submit it to the Apache::DBI maintainer (if you haven't already) The patch didn't work. ref $Connected{$Idx} is always 'DBI::db' -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
Apache::DBI and DBIx::*
What does a DBIx::* module have to do in order to correctly call Apache::DBI's no-op version of disconnect() when running under mod_perl with Apache::DBI? Below is an example that illustrates a bug I found when using a particular DBIx:: module. --- package MyTest; use strict; use Apache::DBI; use DBIx::ContextualFetch; sub handler { my($r) = shift; my $dbh = DBI-connect('dbi:...', 'myuser', 'mypass', { RootClass = 'DBIx::ContextualFetch' }); $r-send_http_header('text/plain'); $dbh-do('...any valid sql...') ? print 'OK' : print 'Failed'; $dbh-disconnect; # This calls the wrong disconnect()! return 200; } 1; --- Run it under httpd -X to further isolate the problem and you'll see that the first request works, but all subsequent requests fail. This happens because the disconnect() call actually calls the real disconnect method instead of the Apache::DBI implementation, which is a no-op. On the next request, Apache::DBI happily provides what is now a disconnected $dbh. Any attempt to use that $dbh fails, obviously. If you enable Apache::DBI's debugging output ($Apache::DBI::DEBUG = 1), you'll see that the correct connect() method is called. That is, only one connection is made and then re-used. So, getting back to my original question, who is at fault here? Is this an Apache::DBI bug, a DBIx::ContextualFetch bug, or something else? One easy fix is to add a disconnect() method to DBIx::ContextualFetch that detects when Apache::DBI is in use. Example: sub DBIx::ContextualFetch::disconnect { if($ENV{'MOD_PERL'} $Apache::DBI::VERSION) { # Do nothing when Apache::DBI is in use return 1; } shift-SUPER::disconnect(@_); } But isn't Apache::DBI supposed to be transparent and do all this stuff for me? Or are all bets off when using a DBIx module? If so, what is a DBIx author supposed to do to be a good Apache::DBI citizen? -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
Re: Apache::DBI and DBIx::*
On Fri, 13 Aug 2004 15:32:03 -0400, Perrin Harkins [EMAIL PROTECTED] wrote: On Fri, 2004-08-13 at 15:25, John Siracusa wrote: What does a DBIx::* module have to do in order to correctly call Apache::DBI's no-op version of disconnect() when running under mod_perl with Apache::DBI? It needs to not set RootClass. Apache::DBI essentially subclasses DBI, which is what RootClass does as well. Er, yeah, essentially :) All the crazy re-blessing that goes on is quite a mess, IMO. So what you're saying is that DBIx::* and Apache::DBI will simply never get along because they both want to do the same thing, but use different (and apparently incompatible) methods to do so? Run it under httpd -X to further isolate the problem and you'll see that the first request works, but all subsequent requests fail. This happens because the disconnect() call actually calls the real disconnect method instead of the Apache::DBI implementation, which is a no-op. Why call disconnect at all? Are you trying to run this as normal CGI too? The first answer is that I'm calling disconnect because it's The Right Thing To Do. Maybe some people think just letting things go out of scope is more (mod_)perl-ish, but I always wonder if those people don't call close(FILE) either ;) Anyway, I'm not one of those people. The second answer is that it's common (and usually desirable) for certain DBI-using modules to be used both in both web and offline contexts. (The example was heavily simplified, obviously.) -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
Re: Apache::DBI and DBIx::*
On Fri, 13 Aug 2004 16:45:59 -0400, Perrin Harkins [EMAIL PROTECTED] wrote: On Fri, 2004-08-13 at 16:37, Stas Bekman wrote: IMHO, that should be folded into DBI::Pool I'm not really interested in tackling pooling, since I don't plan to run threads. All that I really want my module to do is extend the DBI-connect_cached() method by adding the cleanup handler stuff from Apache::DBI. Even without threads, wouldn't you rather have each apache child pulling connections from a shared, server-wide pool rather than holding onto at least one connection a piece whether they need it or not? With the Apache::DBI system on a typical db-backed web site, the max number of simultaneous (mod_perl) requests is pretty much limited by the max number of simultaneous open database connections (since, long term, every apache child will be hanging onto at least one db connection). A server-wide pool removes that limitation, allowing each request to retain, use, and then release any number of connections (possibly zero) within the course of a single request. Maybe that'd lead to too much contention, I don't know, but I assumed something like that was a long-term mod_perl2/apache2/perl6 goal. Or maybe it's just a personal fantasy... :) -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
Re: Apache::DBI and DBIx::*
On Fri, 13 Aug 2004 17:02:27 -0400, Perrin Harkins [EMAIL PROTECTED] wrote: Now that Perl has lexically scoped filehandles, there isn't any reason to explicitly call close() in most cases. ;) Tsk, for shame. Just wait until you forget to call close() after writing to a file... ;) That's the point actually -- perl closes it for me when it goes out of scope. Ah, but perl doesn't check the return value! :) Something tells me you haven't been bitten by this bug yet, but let me save you the grief. When, say, your disk fills up and you let that file handle go out of scope, close() will silently fail when trying to flush the buffers to disk. The moral of the story: always call close() explicitly *and check the return value* when writing to a file. -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
Checking the return value of close() (was: Apache::DBI and DBIx::*)
On 8/13/04 5:23 PM, Perrin Harkins wrote: On Fri, 2004-08-13 at 17:15, John Siracusa wrote: Something tells me you haven't been bitten by this bug yet, but let me save you the grief. When, say, your disk fills up and you let that file handle go out of scope, close() will silently fail when trying to flush the buffers to disk. If you're concerned about that, you should actually check the return value of print() as well. Believe me, everyone should be concerned about that :) Also, the return value from print() is not always useful. In the situation I described, for example, print will happily return 1 so long as what it's printing fits in the output buffer, regardless of whether or not the data is actually going to make it to the disk. Checking the return value from close() gives a more reliable answer, and you only have to do it once at the end. -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
Re: Apache::DBI and DBIx::*
On 8/13/04 5:22 PM, Perrin Harkins wrote: On Fri, 2004-08-13 at 17:05, John Siracusa wrote: Even without threads, wouldn't you rather have each apache child pulling connections from a shared, server-wide pool rather than holding onto at least one connection a piece whether they need it or not? Sure. Can you figure out a way to do it? Probably not in Perl 5 and apache 1.x, but I hope Perl 6, apache 2, and mod_(perl6|parrot) will be flexible enough... You actually have a site where you can run more apache children than database connections? I have never seen such a beast. Maybe your database is just too beefy? :) I've worked on sites that would routinely bump into a database connection limit of ~200 during traffic spikes. (And yes, of course static content was served elsewhere :) Maybe that'd lead to too much contention, I don't know, but I assumed something like that was a long-term mod_perl2/apache2/perl6 goal. Or maybe it's just a personal fantasy... :) Perl6 would presumably mean mod_perl 3. ...or mod_parrot or something, especially if this Parrot DBI-like-core thing takes off (I forget the name they're using) Anyway, the pooling thing is mostly driven by how much Java people hype it. The usefulness of pooling is pretty limited for a site that actually uses database connections on every request. I've worked on sites that use a session (MySQL) database connection on every request, but don't use a main (Postgres) database connection nearly that often. If that main database is shared by several sites/apps, it can become the bottleneck. Maybe read-only replication would help, but it still seems wasteful. -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
Re: Checking the return value of close() (was: Apache::DBI and DBIx::*)
On 8/13/04 10:34 PM, John Siracusa wrote: In the situation I described, for example, print will happily return 1 so long as what it's printing fits in the output buffer, regardless of whether or not the data is actually going to make it to the disk. Er, that should read regardless of whether or not the disk is full, since making it to disk is outside the scope of Perl's core functions (and may be outside the scope of the OS if the hardware lies :) -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
Re: [PATCH] Apache::DBI support for subclassed DBI connections
On 8/13/04 5:43 PM, Perrin Harkins wrote: This patch should make Apache::DBI work with subclassed DBI connections. The only downside is that it makes ALL of your cached connections subclassed if you give it one that is subclassed. Given how most people use DBI subclasses (for universal functionality on all DBI connections), this is probably not an issue. Cool, I'll try it out on Monday. If it works, you should submit it to the Apache::DBI maintainer (if you haven't already) -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
mod_perl 2 and DBI connection pooling
What is the status of DBI connection pooling (a la Apache::DBI) in mod_perl 2? The 2.0 guide says, a replacement for Apache::DBI based on the tipool will allow to reuse database connections between multiple threads of the same process. will allow? Does that mean it's not done yet? How are people using DBI and mod_perl 2 in production environments? -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
Re: ANNOUNCE: MasonX::WebApp 0.01
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
Re: ANNOUNCE: MasonX::WebApp 0.01
On 5/12/04 12:30 PM, Dave Rolsky wrote: On Wed, 12 May 2004, John Siracusa wrote: 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: [ much stuff snipped ] I think one of the reasons you can do your stuff that way is that you are using the Mason Interp object to dispatch to Mason, rather than the ApacheHandler object. Mason's ApacheHandler has no mechanism for being handed a set of arguments, it insists on getting them itself (from an Apache::Request or CGI object), which is a little annoying. I hope to make ApacheHandler a little less self-contained in the next major release (1.4), but for now I'm stuck with nasty hacks. ...which begs the question, why not use an interp in MasonX::WebApp instead of trying to wedge in behind Mason's ApacheHandler? After all, I think that's the advice you originally gave me way back when... :) -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
Re: err_headers_out vs headers_out
On 10/18/03 11:18 AM, Ged Haywood wrote: http://www.mail-archive.com/[EMAIL PROTECTED]/msg36041.html Whoop, I think this is the post I was looking for earlier :) http://ken.coar.org/burrow/index?month=2003-07#511 -John