Re: PerlCleanupHandler
Hi, Michael Peppler wrote: > We're seeing a number of requests where the write from apache to the > client browser times out and the SIGALRM signal fires. Our > Apache::Registry scripts in that case don't clean up correctly, > leaving session lock files around, which of course causes that > particular session to be screwed up for a while. > > My question is would a Cleanup handler still be called in this case? > > ( I'm asking because it's a large site, and I can't just add code left > and right... :-) I've seen something similar - when the client browser times out, execution seems to stop mid-Print statement, and mod_Perl gets ready for the next request, without cleaning up objects present (or, at least, without calling ->DESTROY). IIRC, "END" blocks are called by mod_Perl, rather than Perl itself, since Perl normally calls them only when the interpreter is about to shut down. END blocks still get called in this situation, so if you run foo.pl and manage to hit stop before it's printed its output... my $object = new Foo::Bar; # blah blah blah print "The answer is ", $object->answer; sub END { warn "bye!\n" }; and in Bar.pm sub DESTROY { warn "outta here!\n" }; ... you get "bye!" in the error log, but not "outta here!". This obviously plays merry hell with database handles on transactioned databases, session locks, etc. I don't know for sure if SIGALRM is involved in this, though that seems plausible. My guess is that if END gets called, so will a cleanup handler. More disturbingly, there seem to be very occasional cases where the cleanup stuff doesn't do what's expected of it, so I suggest you keep an eye on what's happening. Our current workaround - not a good one - is to kill $$ when objects don't get cleaned up correctly. Hope this helps... -- Tim Sweetman A L Digital "When in Rome, burn it!"
Re: PerlCleanupHandler
On Wed, 9 Aug 2000, Michael Peppler wrote: > Hi, > > We're seeing a number of requests where the write from apache to the > client browser times out and the SIGALRM signal fires. Our > Apache::Registry scripts in that case don't clean up correctly, > leaving session lock files around, which of course causes that > particular session to be screwed up for a while. > > My question is would a Cleanup handler still be called in this case? yes. but, the proper solution is for mod_perl to change usage of hard_timeout() to soft_timeout(). hard_timeout() does a longjmp out to the accept loop, whereas soft_timeout() just sets $r->connection->aborted to 1, so all apache i/o calls become noops, but the script continues to run until finished. i don't know why we used hard_timeout() in the first place. if a script wants to abort, they'll need to do it themselves, something along the lines of: $r->print('foo'); die if $r->connection->aborted; Index: Apache/Apache.pm === RCS file: /home/cvs/modperl/Apache/Apache.pm,v retrieving revision 1.52 diff -u -r1.52 Apache.pm --- Apache/Apache.pm2000/08/15 04:35:13 1.52 +++ Apache/Apache.pm2000/08/31 05:38:36 @@ -68,7 +68,7 @@ $_[1] ||= ""; #$_[1] = " " x $bufsiz unless defined $_[1]; #XXX? -$r->hard_timeout("Apache->read"); +$r->soft_timeout("Apache->read"); while($bufsiz) { $nrd = $r->read_client_block($buf, $bufsiz) || 0; @@ -113,7 +113,7 @@ return 0; } -$r->hard_timeout("Apache->read"); +$r->soft_timeout("Apache->read"); while($bufsiz) { $nrd = $r->get_client_block($buf, $bufsiz) || 0; @@ -425,7 +425,7 @@ looping until it gets all of C<$bytes_to_read> or a timeout happens. In addition, this method sets a timeout before reading with -C<$r-Ehard_timeout>. +C<$r-Esoft_timeout>. =item $r->get_remote_host @@ -909,7 +909,7 @@ =item $r->print( @list ) This method sends data to the client with C<$r-Ewrite_client>, but first -sets a timeout before sending with C<$r-Ehard_timeout>. This method is +sets a timeout before sending with C<$r-Esoft_timeout>. This method is called instead of CORE::print when you use print() in your mod_perl programs. This method treats scalar references specially. If an item in @list is a Index: src/modules/perl/Apache.xs === RCS file: /home/cvs/modperl/src/modules/perl/Apache.xs,v retrieving revision 1.105 diff -u -r1.105 Apache.xs --- src/modules/perl/Apache.xs 2000/08/31 03:39:45 1.105 +++ src/modules/perl/Apache.xs 2000/08/31 05:38:48 @@ -1033,7 +1033,7 @@ } else { CV *cv = GvCV(gv_fetchpv("Apache::write_client", FALSE, SVt_PVCV)); - hard_timeout("mod_perl: Apache->print", r); + soft_timeout("mod_perl: Apache->print", r); PUSHMARK(mark); #ifdef PERL_OBJECT (void)(*CvXSUB(cv))(cv, pPerl); /* &Apache::write_client; */
Re: PerlCleanupHandler
On Fri, 11 Aug 2000, Tim Sweetman wrote: > I've seen something similar - when the client browser times out, > execution seems to stop mid-Print statement, and mod_Perl gets ready for > the next request, without cleaning up objects present (or, at least, > without calling ->DESTROY). this should be fixed with the hard_timeout -> soft_timeout change. > IIRC, "END" blocks are called by mod_Perl, rather than Perl itself, > since Perl normally calls them only when the interpreter is about to > shut down. END blocks still get called in this situation, so if you run > foo.pl and manage to hit stop before it's printed its output... right, because mod_perl runs Apache::Registry END blocks in a cleanup. > More disturbingly, there seem to be very occasional cases where the > cleanup stuff doesn't do what's expected of it, so I suggest you keep an > eye on what's happening. Our current workaround - not a good one - is to > kill $$ when objects don't get cleaned up correctly. hmm, the hard_timeout() may have left Perl in a confused state. if you're still seeing this behavior with the soft_timeout() change, i'd appreciate any details you have on this.
Re: PerlCleanupHandler vs register_cleanup
On Thu, 24 Aug 2000, Paul G. Weiss wrote: > What is the difference between doing > $r->push_handlers('PerlCleanupHandler', \&function); > and > $r->register_cleanup(\&function); The same: http://www.modperl.com/book/chapters/ch9.html#Server_Core_Functions The register_cleanup() method registers a subroutine that will be called after the logging stage of a request. This is much the same as installing a cleanup handler with the PerlCleanupHandler directive. See Chapter 7 for some practical examples of using register_cleanup(). _ Stas Bekman JAm_pH -- Just Another mod_perl Hacker http://stason.org/ mod_perl Guide http://perl.apache.org/guide mailto:[EMAIL PROTECTED] http://apachetoday.com http://jazzvalley.com http://singlesheaven.com http://perlmonth.com perl.org apache.org
Re: PerlCleanupHandler firing too early?
Trey Hyde wrote: My PerlCleanupHandler seems to be firing before the content phase has finished processing the page. The handler pretty much looks like sub handler { my ($r) = @_; undef $Foo::bar; undef $Foo::baz; return OK; } It's being invoked in a virtual host apache conf segment with PerlCleanupHandler Apache::CleanupFoo If I don't comment out the PerlCleanupHandler line pieces of the application that rely on any variable that I undef in the Cleanup phase will crash. In the error log it doesn't _LOOK_ like the handler is being called early. The log yields exactly what I would expect it to. PID 1000 REWRITE CALLED initial: 1 main: 0 PID 1000 REWRITE CALLED initial: 0 main: 0 PID 1000 REWRITE CALLED initial: 0 main: 1 PID 1000 AUTHENTICATION CALLED BUNCH OF PERL ERRORS GO HERE (can't call method foo on undefined value and the like) PID 1000 REWRITE CALLED initial:0 main: 1 (rewriting /cgi-bin/error/error.pl) PID 1000 LOGGER CALLED (uri: error.pl) PID 1000 CLEANUP CALLED (uri: mod_perl app) I'm running on Apache/1.3.27 (Unix) mod_perl/1.26 w/ embperl 1.3.6. Does anyone have an idea of what is going on here (or what I'm doing wrong here?). Am I right in thinking that the CleanupHandler isn't supposed to have any effect on the code _running_ in the current or subsequent processes? In summary, leave Cleanup handler in everything that I undef in the cleanup handler gets undef'ed in the middle of running the code, if I removed the CleanupHandler the app works as intended. In the current request the CleanupHandler happens the last. You can visually see that using Apache::ShowRequest http://search.cpan.org/author/DOUGM/Apache-Module-0.11/lib/Apache/ShowRequest.pm However you don't show the code that you have the problem with, so certainly we have no clue why does it fail. If your cleanup handler affects global variable in the package, certainly you may have an impact on the subsequent requests running in the same process. If you still have this problem, reduce the problematic code to the very minimum (2-3 lines of code?), so that the problem can be still reproduced and post it here. __ Stas BekmanJAm_pH --> Just Another mod_perl Hacker http://stason.org/ mod_perl Guide ---> http://perl.apache.org mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com http://modperlbook.org http://apache.org http://ticketmaster.com
Re: PerlCleanupHandler called from default-handler
Tom Murphy wrote: I have written a Apache::DBILogger style log mechanism. It is enabled via the perl.conf in the Server context as: PerlCleanupHandler NC::LogHandler It works correctly, except for the fact that request handle by the default-handler do not call this handler. The mod_perl cookbook makes note that: "..a C module has to specifically want this processing to occur-it is not called automatically." well, what we said is true, but you're reading it the wrong way :) basically, all of the Perl*Handler directives - from PerlPostReadRequestHandler to PerlCleanupHandler - can be thought of as parts of the request cycle. however, this is true for all but the PerlCleanupHandler, which really isn't part of the request cycle - mod_perl just makes it look that way. what's really happening is that mod_perl is hooking your Perl handler into the per-request cleanup that Apache offers all C modules (mod_perl included). so it _should_ be called for every request it is configured to run for (should being highly caveated - people have reported that _sometimes_ this doesn't really happen). understanding that is A Good Thing. however, it's not going to help you very much here :) How do I allow for this handler to be called on all requests? Note I also tried this as a PerlLogHandler to no avail. if the PerlLogHandler doesn't get called then you probably have a configuration problem. both of these can exist on their own, outside of a container. something like PerlLogHandler NC::LogHandler ... if that doesn't show your log handler running then you need to check your error log for errors and make sure your handler compiles under perl -cw or something - if the log handler errors out, you really can't see it unless you look. of course, all this assumes that you built with EVERYTHING=1 - check Apache::Status to make sure. another thing you can try if that doesn't work out is compiling a debugging mod_perl (PERL_DEBUG=1 and PERL_TRACE=1 when building) and set PerlSetEnv MOD_PERL_TRACE on and watch the verbose output. HTH --Geoff