Practical mod_perl, from O'Reilly. | 18
Practical mod_perl: Chapter 6: Coding with mod_perl in Mind
Perl Specifics in the mod_perl Environment
In the following sections, we discuss the specifics of Perl's behavior under mod_perl.
exit( )
Perl's core exit( )
function shouldn't
be used in mod_perl code. Calling it causes the mod_perl process to exit, which
defeats the purpose of using mod_perl. The Apache::exit(
)
function should be used instead. Starting with Perl Version 5.6.0,
mod_perl overrides exit( )
behind the scenes using
CORE::GLOBAL::
, a new magical
package.
The CORE:: Package
use subs qw(exit);
exit( ) if $DEBUG;
sub exit { warn "exit( ) was called"; }
Apache::Registry
and Apache::PerlRun
override exit( )
with Apache::exit(
)
behind the scenes; therefore, scripts running under these modules don't
need to be modified to use Apache::exit( )
.
If CORE::exit( )
is used in scripts
running under mod_perl, the child will exit, but the current request won't be
logged. More importantly, a proper exit won't be performed. For example, if
there are some database handles, they will remain open, causing costly memory
and (even worse) database connection leaks.
If the child process needs to be killed, Apache::exit(Apache::Constants::DONE)
should be used instead. This will cause the server to exit gracefully, completing
the logging functions and protocol requirements.
If the child process needs to be killed cleanly after the request
has completed, use the $r->child_terminate
method.
This method can be called anywhere in the code, not just at the end. This method
sets the value of the MaxRequestsPerChild
configuration
directive to 1
and clears the keepalive
flag. After the request is serviced, the current connection is broken because
of the keepalive
flag, which is set to false, and
the parent tells the child to cleanly quit because MaxRequestsPerChild
is smaller than or equal to the number of requests served.
In an Apache::Registry
script you
would write:
Apache->request->child_terminate;
and in httpd.conf:
PerlFixupHandler "sub { shift->child_terminate }"
You would want to use the latter example only if you wanted the child to terminate every time the registered handler was called. This is probably not what you want.
You can also use a post-processing handler to trigger child termination. You might do this if you wanted to execute your own cleanup code before the process exits:
my $r = shift;
$r->post_connection(\&exit_child);
sub exit_child {
# some logic here if needed
$r->child_terminate;
}
This is the code that is used by the Apache::SizeLimit
module, which terminates processes that grow bigger than a preset quota.
die( )
die( )
is usually used to abort the
flow of the program if something goes wrong. For example, this common idiom
is used when opening files:
open FILE, "foo" or die "Cannot open 'foo' for reading: $!";
If the file cannot be opened, the script will die(
)
: script execution is aborted, the reason for death is printed, and
the Perl interpreter is terminated.
You will hardly find any properly written Perl scripts that don't
have at least one die( )
statement in them.
CGI scripts running under mod_cgi exit on completion, and the
Perl interpreter exits as well. Therefore, it doesn't matter whether the interpreter
exits because the script died by natural death (when the last statement in the
code flow was executed) or was aborted by a die( )
statement.
Under mod_perl, we don't want the process to quit. Therefore,
mod_perl takes care of it behind the scenes, and die(
)
calls don't abort the process. When die( )
is called, mod_perl logs the error message and calls Apache::exit(
)
instead of CORE::die( )
. Thus, the script
stops, but the process doesn't quit. Of course, we are talking about the cases
where the code calling die( )
is not wrapped inside
an exception handler (e.g., an eval { }
block)
that traps die( )
calls, or the $SIG{_
_DIE_ _}
sighandler, which allows you to override the behavior of die(
)
(see Chapter 21). The reference section at the end of this chapter
mentions a few exception-handling modules available from CPAN.
Created: March 27, 2003
Revised: July 23, 2003
URL: https://webreference.com/programming/perl/mod_perl/chap6/2