| home / programming / perl / mod_perl / chap6 / 3 | [previous] [next] |
|
|
You often need to reload modules in development and production environments. mod_perl tries hard to avoid unnecessary module reloading, but sometimes (especially during the development process) we want some modules to be reloaded when modified. The following sections discuss issues related to module loading and reloading.
Under mod_perl, @INC can be modified
only during server startup. After each request, mod_perl resets @INC's
value to the one it had before the request.
If mod_perl encounters a statement like the following:
use lib qw(foo/bar);
it modifies @INC only for the period
during which the code is being parsed and compiled. Afterward, @INC
is reset to its original value. Therefore, the only way to change @INC
permanently is to modify it at server startup.
There are two ways to alter @INC
at server startup:
PerlSetEnv PERL5LIB /home/httpd/perl
or:
PerlSetEnv PERL5LIB /home/httpd/perl:/home/httpd/mymodules
use lib qw(/home/httpd/perl /home/httpd/mymodules);1;
As always, the startup file needs to be loaded from httpd.conf:
PerlRequire /path/to/startup.pl
To make sure that you have set @INC
correctly, configure perl-status into your server,
as explained in Chapter 21. Follow the "Loaded Modules" item in the
menu and look at the bottom of the generated page, where the contents of @INC
are shown:
@INC =/home/httpd/mymodules/home/httpd/perl/usr/lib/perl5/5.6.1/i386-linux/usr/lib/perl5/5.6.1/usr/lib/perl5/site_perl/5.6.1/i386-linux/usr/lib/perl5/site_perl/5.6.1/usr/lib/perl5/site_perl./home/httpd/httpd_perl//home/httpd/httpd_perl/lib/perl
As you can see in our setup, we have two custom directories prepended at the beginning of the list. The rest of the list contains standard directories from the Perl distribution, plus the $ServerRoot and $ServerRoot/lib/perl directories appended at the end (which mod_perl adds automatically).
When working with mod_cgi, you can change the code and rerun the CGI script from your browser to see the changes. Since the script isn't cached in memory, the server starts up a new Perl interpreter for each request, which loads and recompiles the script from scratch. The effects of any changes are immediate.
The situation is different with mod_perl, since the whole idea
is to get maximum performance from the server. By default, the server won't
spend time checking whether any included library modules have been changed.
It assumes that they weren't, thus saving the time it takes to stat(
) the source files from any modules and libraries you use(
) and require( ) in your script.
If the scripts are running under Apache::Registry,
the only check that is performed is to see whether your main script has been
changed. If your scripts do not use( ) or require(
) any other Perl modules or packages, there is nothing to worry about.
If, however, you are developing a script that includes other modules, the files
you use( ) or require( )
aren't checked for modification, and you need to do something about that.
There are a couple of techniques to make a mod_perl-enabled server recognize changes in library modules. They are discussed in the following sections.
The simplest approach is to restart the server each time you apply some change to your code. Restarting techniques are covered in Chapter 5. After restarting the server about 50 times, you will tire of it and look for other solutions.
Help comes from the Apache::StatINC
module. When Perl pulls in a file with require( ),
it stores the full pathname as a value in the global hash %INC
with the filename as the key. Apache::StatINC looks
through %INC and immediately reloads any file that
has been updated on the disk.
To enable this module, add these two lines to httpd.conf:
PerlModule Apache::StatINCPerlInitHandler Apache::StatINC
To be sure it really works, turn on debug mode on your development
system by adding PerlSetVar StatINCDebug On to
your configuration file. You end up with something like this:
PerlModule Apache::StatINCPerlInitHandler Apache::StatINC<Location /perl>SetHandler perl-scriptPerlHandler Apache::RegistryOptions ExecCGIPerlSendHeader OnPerlSetVar StatINCDebug On</Location>
Be aware that only the modules located in @INC
are reloaded on change, and you can change @INC
only before the server has been started (in the startup file).
Note the following trap: because ".",
the current directory, is in @INC, Perl knows how
to require( ) files with pathnames relative to
the current script's directory. After the code has been parsed, however, the
server doesn't remember the path. So if the code loads a module MyModule
located in the directory of the script and this directory is not in @INC,
you end up with the following entry in %INC:
'MyModule.pm' => 'MyModule.pm'
When Apache::StatINC tries to check
whether the file has been modified, it won't be able to find the file, since
MyModule.pm is not in any of the paths in @INC.
To correct this problem, add the module's location path to @INC
at server startup.
| home / programming / perl / mod_perl / chap6 / 3 | [previous] [next] |
Created: March 27, 2003
Revised: July 23, 2003
URL: http://webreference.com/programming/perl/mod_perl/chap6/3