| home / programming / perl / mod_perl / chap6 / 3 | [previous] [next] |
|
|
Example 6-24: reread_conf.pl
use vars qw(%MODIFIED $firstname $surname);use CGI ( );use strict;my $q = CGI->new;print $q->header(-type => 'text/plain');my $config_file = "./config.pl";reread_conf($config_file);print $q->p("$firstname $surname holds the patch pumpkin" ."for this Perl release.");sub reread_conf {my $file = shift;return unless defined $file;return unless -e $file and -r _;my $mod = -M _;unless ($MODIFIED{$file} and $MODIFIED{$file} == $mod) {unless (my $result = do $file) {warn "couldn't parse $file: $@" if $@;warn "couldn't read $file: $!" unless defined $result;warn "couldn't run $file" unless $result;}$MODIFIED{$file} = $mod; # Update the MODIFICATION time}}
You should be using (stat $file)[9]
instead of -M $file if you are modifying the $^T
variable. This is because -M returns the modification
time relative to the Perl interpreter startup time, set in $^T.
In some scripts, it can be useful to reset $^T
to the time of the script invocation with "local
$^T = time( )". That way, -M and other
-X file status tests are performed relative to
the script invocation time, not the time the process was started.
If your configuration file is more sophisticated--for example,
if it declares a package and exports variables--the above code will work just
as well. Variables need not be import( )ed again:
when do( ) recompiles the script, the originally
imported variables will be updated with the values from the reloaded code.
Dynamically updating configuration files
The CGI script below allows a system administrator to dynamically update a configuration file through a web interface. This script, combined with the code we have just seen to reload the modified files, gives us a system that is dynamically reconfigurable without having to restart the server. Configuration can be performed from any machine that has a browser.
Let's say we have a configuration file like the one in Example 6-25.
Example 6-25: Book/MainConfig.pm
package Book::MainConfig;use strict;use vars qw(%c);%c = (name => "Larry Wall",release => "5.000",comments => "Adding more ways to do the same thing :)",other => "More config values",colors => { foreground => "black",background => "white",},machines => [qw( primary secondary tertiary )],);
We want to make the variables name,
release, and comments
dynamically configurable. We'll need a web interface with an input form that
allows modifications to these variables. We'll also need to update the configuration
file and propagate the changes to all the currently running processes.
Let's look at the main stages of the implementation:
The only part that seems hard to implement is a configuration file update, for a couple of reasons. If updating the file breaks it, the whole service won't work. If the file is very big and includes comments and complex data structures, parsing the file can be quite a challenge.
So let's simplify the task. If all we want is to update a few variables, why don't we create a tiny configuration file containing just those variables? It can be modified through the web interface and overwritten each time there is something to be changed, so that we don't have to parse the file before updating it. If the main configuration file is changed, we don't care, because we don't depend on it any more.
The dynamically updated variables will be duplicated in the main file and the dynamic file. We do this to simplify maintenance. When a new release is installed, the dynamic configuration file won't exist--it will be created only after the first update. As we just saw, the only change in the main code is to add a snippet to load this file if it exists and was changed.
This additional code must be executed after the main configuration file has been loaded. That way, the updated variables will override the default values in the main file. See Example 6-26.
| 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