MySQL and Perl for the Web: Chapter 3 Section 3 (2/6)
[previous][next] |
Improving Performance with mod_perl
Diagnostic Output Generation
It's often useful to tell Perl to generate error messages that help you determine that your scripts have problems and what to do about it. You may find the following techniques useful for getting diagnostic information and debugging your scripts:
Use the
-w
option on the#!
line at the beginning of your scripts, to tell Perl to emit warnings for questionable constructs:#! /usr/bin/perl -w
mod_perl
doesn't use the path name, but it will notice the-w
option and turn on warning mode.Include a
use diagnostics
line to tell Perl to print suggestions about the causes of problems:use diagnostics;
- Install the
Apache::DBdebugger
module and preload it in themod_perl
startup file. This module isn't included with Apache ormod_perl
by default, but you can get it from https://cpan.perl.org/.
Output resulting from these techniques will go to the Apache error log, so you'll need to look there for diagnostic messages. Naturally, you should try to write your scripts to eliminate warnings if possible. If you use the -w
option on the #!
line, the error log can become useless if you have so many warnings being produced that it becomes difficult to tell what's important and what isn't. Try to modify your scripts to make the warnings go away.
Script Environment Contamination
With a standalone script, the environment provided by the external Perl process that executes the script goes away when the script terminates. The processes are independent and don't affect each other. With mod_perl
, this is not true, because a given httpd
process can run several scripts over the course of its lifetime, and there is state information in the Perl interpreter that persists from request to request. This is essential behavior for implementing some kinds of services such as persistent database connections, but it can lead to problems as well. If you're sloppy in your programming, one script can pollute the environment for subsequent scripts. Here's a simple example:
#! /usr/bin/perl -w
print "Content-Type: text/html\n\n";
print $x++, "\n";
Put this script in your cgi-bin
directory as increment.pl
, and then request it several times in quick succession. You'll see the value 0 in your browser window each time. Then move it to cgi-perl
and request it from there several more times. Now you'll see a series of numbers that is "sort of" random but generally increasing. (The order depends on the order in which the httpd
children are selected to process your requests.) The reason this occurs is that $x
is a global variable but is never initialized. The first time any given child executes increment.pl
, the value of $x
is 0. The next time, the script inherits the previous value and increments that.
Don't use variables as global variables without declaring them as such or without initializing them first. The increment.pl
script doesn't follow this principle, so it needs some modification to be a better citizen. Fortunately, that's easy to do. Just declare $x
to be global explicitly with use vars
, and then initialize it:
#! /usr/bin/perl -w
use strict;
use vars qw($x);
$x = 0;
print "Content-Type: text/html\n\n";
print $x++, "\n";
The use strict
line isn't actually required to make the script yield consistent results (0 each time it's invoked); it's just good programming practice to use it.
[previous][next] |
Created: July 13, 2001
Revised: July 13, 2001