MySQL and Perl for the Web: Chapter 3 Section 3 (5/6) | WebReference

MySQL and Perl for the Web: Chapter 3 Section 3 (5/6)

To page 1To page 2To page 3To page 4current pageTo page 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.

To page 1To page 2To page 3To page 4current pageTo page 6
[previous][next]


Created: July 13, 2001
Revised: July 13, 2001

URL: https://webreference.com/programming/perl/mysqlperl/chap3/3/5.html