stas2003/05/29 20:18:03
Modified:src/docs/2.0/user/handlers http.pod
Log:
add cleanup handler / pool cleanup handler examples and discussions
Revision ChangesPath
1.18 +196 -4modperl-docs/src/docs/2.0/user/handlers/http.pod
Index: http.pod
===
RCS file: /home/cvs/modperl-docs/src/docs/2.0/user/handlers/http.pod,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- http.pod 6 Mar 2003 04:32:06 - 1.17
+++ http.pod 30 May 2003 03:18:03 - 1.18
@@ -1012,7 +1012,7 @@
SetHandler perl-script
- PerlResponseHandler ModPerl::Registry
+ PerlResponseHandler MyApache::WorldDomination
C set to
@@ -1202,8 +1202,15 @@
=head2 PerlCleanupHandler
-The cleanup stage is used to execute some code when the request has
-been served.
+The cleanup stage is used to execute some code immediately after the
+request has been served (the client went away).
+
+There are several usages for this use phase. The obvious one is to run
+a cleanup code, for example removing temporarily created files. The
+less obvious is to use this phase instead of
+C> if the logging operation is time
+consuming. This approach allows to free the client as soon as the
+response is sent.
This phase is of type
C>.
@@ -1211,7 +1218,192 @@
The handler's configuration scope is
C>.
-META: examples are needed (for now mod_perl 1.0 docs apply)
+There are two different ways a cleanup handler can be registered:
+
+=over
+
+=item 1 Using the C phase
+
+ PerlCleanupHandler MyApache::Cleanup
+
+or:
+
+ $r->push_handlers(PerlCleanupHandler => \&cleanup);
+
+This method is identical to all other handlers.
+
+In this technique the C callback accepts C<$r> as its only
+argument.
+
+=item 2 Using cleanup_register() method acting on the request object pool
+
+Since a request object pool is destroyed at the end of each request,
+we can register a cleanup callback which will be executed just before
+the pool is destroyed. For example:
+
+$r->pool->cleanup_register(\&cleanup, $arg);
+
+The important difference from using the C handler,
+is that here you can pass any argument to the callback function, and
+no C<$r> argument is passed by default. Therefore if you need to pass
+any data other than C<$r> you may want to use this technique.
+
+=back
+
+Here is an example where the cleanup handler is used to delete a
+temporary file. The response handler is running C and stores
+the output in temporary file, which is then used by
+C<$r-Esendfile> to send the file's contents. We use
+C to push C to do unlink the file
+at the end of the request.
+
+ package MyApache::Cleanup1;
+
+ use strict;
+ use warnings FATAL => 'all';
+
+ use File::Spec::Functions qw(catfile);
+
+ use Apache::RequestRec ();
+ use Apache::RequestIO ();
+ use Apache::RequestUtil ();
+
+ use Apache::Const -compile => qw(OK DECLINED);
+ use APR::Const-compile => 'SUCCESS';
+
+ my $file = catfile "/tmp", "data";
+
+ sub handler {
+ my $r = shift;
+
+ $r->content_type('text/plain');
+
+ local @ENV{qw(PATH BASH_ENV)};
+ qx(/bin/ls -l > $file);
+
+ my $status = $r->sendfile($file);
+ die "sendfile has failed" unless $status == APR::SUCCESS;
+
+ $r->push_handlers(PerlCleanupHandler => \&cleanup);
+
+ return Apache::OK;
+ }
+
+ sub cleanup {
+ my $r = shift;
+
+ die "Can't find file: $file" unless -e $file;
+ unlink $file or die "failed to unlink $file";
+
+ return Apache::OK;
+ }
+
+Next we add the following configuration:
+
+
+ SetHandler modperl
+ PerlResponseHandler MyApache::Cleanup1
+
+
+Now when a request to I is made, the contents of the
+current directory will be printed and once the request is over the
+temporary file is deleted.
+
+This response handler has a problem of running in a multiprocess
+environment, since it uses the same file, and several processes may
+try to read/write/delete that file at the same time, wrecking
+havoc. We could have appended the process id C<$$> to the file's name,
+but remember that mod_perl 2.0 code may run in the threaded
+environment, meaning that there will be many threads running in the
+same process and the C<$$> trick won't work any longer. Therefore one
+really has to use this code to create unique, but predictable, file
+names across threads and processes:
+
+ sub unique_id {
+ require APR::OS;
+ return Apache::MPM_IS_THREADED
+ ? "$$." . ${ APR::OS::thread_current() }
+ : $$;
+ }
+
+In the threaded environment it will return a string containin