MySQL and Perl for the Web: Chapter 3 Section 3 (5/6)
[previous][next] |
Improving Performance with mod_perl
Code Caching Effects
Recall that mod_perl
caches compiled scripts. This helps it run scripts faster, but what happens if you change a script? Does mod_perl
continue to execute the cached version? Nope. Apache::Registry
keeps track of the scripts that it has run and checks the modification date of the original file when a script is requested again. If the date has changed, it recompiles the script and the new version is used instead. You can verify this for yourself. Request a script, and then change it and click the Reload button in your browser. You should see the changed output. Then change the script back and click Reload again. You should see the original output. That's what you expect and want to happen.1
However, this behavior doesn't apply to modules pulled into your script via use
or require
. If you change those files, the changes won't be noticed until you restart the server. Another workaround for this problem is to use the Apache::StatINC
module, which forces Apache to check the last modification time even for modules referenced from use
or require
statements. This is a technique best used on a development server, because it slows down Apache. Run perldoc Apache::StatINC
from the command line for more information.
Script caching also is responsible for another mysterious problem. If you use
or require
a library file, that file's code is pulled in to your script, compiled, and cached, as usual. If the file doesn't contain a package
declaration to specify a namespace, however, the code goes into your script's own namespace. This is main
when you run scripts in standalone mode, but scripts run in their own unique namespace under mod_perl
. If your script is called script.pl
, for example, the namespace might be &Apache::ROOT::cgi_2dperl::script_2epl
. Normally, having unique namespaces per script is a good thing, because it helps keep scripts that are run under a given httpd
child from colliding with each other in the main namespace. But it causes a problem for unpackaged library code. Here's why: Suppose you run your script script.pl
that uses a library file MyLib.pm
containing a function lib_func()
. script.pl
will execute properly. Now suppose you have a second script script2.pl
that wants to use MyLib.pm
, too. When the second script executes, mod_perl
sees the use
or require
line for the library file, notices that the file has already been processed and cached, and doesn't bother to recompile it. Then when script2.pl
calls lib_func()
from the library file, an error occurs:
[error] Undefined subroutine
&Apache::ROOT::cgi_2dperl::script2_2epl::lib_func called
This happens because functions in the library file have been compiled, but they're in the namespace for script.pl
, not script2.pl
. To fix this problem, make sure the library file includes a package
declaration, and then invoke its functions using the package
identifier. MyLib.pm
can be written like this:
package MyLib;
sub lib_func
{
...
}
...
After making that change, your scripts should invoke MyLib::lib_func()
rather than lib_func()
.
1. If you're watching the Apache error log while you make changes to a script, you'll probably notice messages that say subroutine xxx redefined
, where xxx is some function in the script. You can make these go away by restarting Apache.
[previous][next] |
Created: July 13, 2001
Revised: July 13, 2001