Return-Path: Delivered-To: apmail-perl-modperl-cvs-archive@www.apache.org Received: (qmail 59707 invoked from network); 23 Apr 2007 21:34:55 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 23 Apr 2007 21:34:55 -0000 Received: (qmail 55745 invoked by uid 500); 23 Apr 2007 21:34:55 -0000 Delivered-To: apmail-perl-modperl-cvs-archive@perl.apache.org Received: (qmail 55736 invoked by uid 500); 23 Apr 2007 21:34:55 -0000 Mailing-List: contact modperl-cvs-help@perl.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: dev@perl.apache.org List-Id: Delivered-To: mailing list modperl-cvs@perl.apache.org Received: (qmail 55719 invoked by uid 99); 23 Apr 2007 21:34:55 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 23 Apr 2007 14:34:54 -0700 X-ASF-Spam-Status: No, hits=-99.5 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 23 Apr 2007 14:34:46 -0700 Received: by eris.apache.org (Postfix, from userid 65534) id D0C481A9838; Mon, 23 Apr 2007 14:34:26 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r531616 - in /perl/Apache-Reload: branches/ tags/ trunk/ trunk/MANIFEST trunk/Makefile.PL trunk/README trunk/Reload.pm Date: Mon, 23 Apr 2007 21:34:26 -0000 To: modperl-cvs@perl.apache.org From: pgollucci@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070423213426.D0C481A9838@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: pgollucci Date: Mon Apr 23 14:34:25 2007 New Revision: 531616 URL: http://svn.apache.org/viewvc?view=rev&rev=531616 Log: importing Apache-Reload based on v0.07 Added: perl/Apache-Reload/branches/ perl/Apache-Reload/tags/ perl/Apache-Reload/trunk/ perl/Apache-Reload/trunk/MANIFEST perl/Apache-Reload/trunk/Makefile.PL perl/Apache-Reload/trunk/README perl/Apache-Reload/trunk/Reload.pm Added: perl/Apache-Reload/trunk/MANIFEST URL: http://svn.apache.org/viewvc/perl/Apache-Reload/trunk/MANIFEST?view=auto&rev=531616 ============================================================================== --- perl/Apache-Reload/trunk/MANIFEST (added) +++ perl/Apache-Reload/trunk/MANIFEST Mon Apr 23 14:34:25 2007 @@ -0,0 +1,4 @@ +Makefile.PL +MANIFEST +Reload.pm +README Added: perl/Apache-Reload/trunk/Makefile.PL URL: http://svn.apache.org/viewvc/perl/Apache-Reload/trunk/Makefile.PL?view=auto&rev=531616 ============================================================================== --- perl/Apache-Reload/trunk/Makefile.PL (added) +++ perl/Apache-Reload/trunk/Makefile.PL Mon Apr 23 14:34:25 2007 @@ -0,0 +1,7 @@ +use ExtUtils::MakeMaker; +# See lib/ExtUtils/MakeMaker.pm for details of how to influence +# the contents of the Makefile that is written. +WriteMakefile( + 'NAME' => 'Apache::Reload', + 'VERSION_FROM' => 'Reload.pm', # finds $VERSION +); Added: perl/Apache-Reload/trunk/README URL: http://svn.apache.org/viewvc/perl/Apache-Reload/trunk/README?view=auto&rev=531616 ============================================================================== --- perl/Apache-Reload/trunk/README (added) +++ perl/Apache-Reload/trunk/README Mon Apr 23 14:34:25 2007 @@ -0,0 +1,106 @@ +NAME + Apache::Reload - Reload changed modules + +SYNOPSIS + In httpd.conf: + + PerlInitHandler Apache::Reload + PerlSetVar ReloadAll Off + + Then your module: + + package My::Apache::Module; + + use Apache::Reload; + + sub handler { ... } + + 1; + +DESCRIPTION + This module is two things. First it is an adaptation of Randal + Schwartz's Stonehenge::Reload module that attempts to be a + little more intuitive and makes the usage easier. + Stonehenge::Reload was written by Randal to make specific + modules reload themselves when they changed. Unlike + Apache::StatINC, Stonehenge::Reload only checked the change time + of modules that registered themselves with Stonehenge::Reload, + thus reducing stat() calls. Apache::Reload also offers the exact + same functionality as Apache::StatINC, and is thus designed to + be a drop-in replacement. Apache::Reload only checks modules + that register themselves with Apache::Reload if you explicitly + turn off the StatINC emulation method (see below). Like + Apache::StatINC, Apache::Reload must be installed as an Init + Handler. + + StatINC Replacement + + To use as a StatINC replacement, simply add the following + configuration to your httpd.conf: + + PerlInitHandler Apache::Reload + + Register Modules Implicitly + + To only reload modules that have registered with Apache::Reload, + add the following to the httpd.conf: + + PerlInitHandler Apache::Reload + PerlSetVar ReloadAll Off + # ReloadAll defaults to On + + Then any modules with the line: + + use Apache::Reload; + + Will be reloaded when they change. + + Register Modules Explicitly + + You can also register modules explicitly in your httpd.conf file + that you want to be reloaded on change: + + PerlInitHandler Apache::Reload + PerlSetVar ReloadAll Off + PerlSetVar ReloadModules "My::Foo My::Bar Foo::Bar::Test" + + Note that these are split on whitespace, but the module list + must be in quotes, otherwise Apache tries to parse the parameter + list. + + Special "Touch" File + + You can also set a file that you can touch() that causes the + reloads to be performed. If you set this, and don't touch() the + file, the reloads don't happen. This can be a great boon in a + live environment: + + PerlSetVar ReloadTouchFile /tmp/reload_modules + + Now when you're happy with your changes, simply go to the + command line and type: + + touch /tmp/reload_modules + + And your modules will be magically reloaded on the next request. + This option works in both StatINC emulation mode and the + registered modules mode. + +PSUEDOHASHES + The short summary of this is: Don't use psuedohashes. Use an + array with constant indexes. Its faster in the general case, its + more guaranteed, and generally, it works. + + The long summary is that I've done some work to get this working + with modules that use psuedo hashes, but its still broken in the + case of a single module that contains multiple packages that all + use psuedohashes. + + So don't do that. + +AUTHOR + Matt Sergeant, matt@sergeant.org + +SEE ALSO + Apache::StatINC, Stonehenge::Reload + Added: perl/Apache-Reload/trunk/Reload.pm URL: http://svn.apache.org/viewvc/perl/Apache-Reload/trunk/Reload.pm?view=auto&rev=531616 ============================================================================== --- perl/Apache-Reload/trunk/Reload.pm (added) +++ perl/Apache-Reload/trunk/Reload.pm Mon Apr 23 14:34:25 2007 @@ -0,0 +1,251 @@ +# $Id: Reload.pm,v 1.16 2001/04/22 18:09:59 matt Exp $ + +package Apache::Reload; + +use strict; + +$Apache::Reload::VERSION = '0.07'; + +use vars qw(%INCS %Stat $TouchTime %UndefFields); + +%Stat = ($INC{"Apache/Reload.pm"} => time); + +$TouchTime = time; + +sub import { + my $class = shift; + my ($package,$file) = (caller)[0,1]; + + $class->register_module($package, $file); +} + +sub package_to_module { + my $package = shift; + $package =~ s/::/\//g; + $package .= ".pm"; + return $package; +} + +sub register_module { + my ($class, $package, $file) = @_; + my $module = package_to_module($package); + + if ($file) { + $INCS{$module} = $file; + } + else { + $file = $INC{$module}; + return unless $file; + $INCS{$module} = $file; + } + + no strict 'refs'; + if (%{"${package}::FIELDS"}) { + $UndefFields{$module} = "${package}::FIELDS"; + } +} + +sub handler { + my $r = shift; + + my $DEBUG = ref($r) && (lc($r->dir_config("ReloadDebug") || '') eq 'on'); + + my $TouchFile = ref($r) && $r->dir_config("ReloadTouchFile"); + + my $TouchModules; + + if ($TouchFile) { + warn "Checking mtime of $TouchFile\n" if $DEBUG; + my $touch_mtime = (stat($TouchFile))[9] || return 1; + return 1 unless $touch_mtime > $TouchTime; + $TouchTime = $touch_mtime; + my $sym = Apache->gensym; + open($sym, $TouchFile) || die "Can't open '$TouchFile': $!"; + $TouchModules = <$sym>; + chomp $TouchModules; + } + + if (ref($r) && (lc($r->dir_config("ReloadAll") || 'on') eq 'on')) { + *Apache::Reload::INCS = \%INC; + } + else { + *Apache::Reload::INCS = \%INCS; + my $ExtraList = + $TouchModules || + (ref($r) && $r->dir_config("ReloadModules")) || + ''; + my @extra = split(/\s+/, $ExtraList); + foreach (@extra) { + if (/(.*)::\*$/) { + my $prefix = $1; + $prefix =~ s/::/\//g; + foreach my $match (keys %INC) { + if ($match =~ /^\Q$prefix\E/) { + $Apache::Reload::INCS{$match} = $INC{$match}; + my $package = $match; + $package =~ s/\//::/g; + $package =~ s/\.pm$//; + no strict 'refs'; +# warn "checking for FIELDS on $package\n"; + if (%{"${package}::FIELDS"}) { +# warn "found fields in $package\n"; + $UndefFields{$match} = "${package}::FIELDS"; + } + } + } + } + else { + Apache::Reload->register_module($_); + } + } + } + + + while (my($key, $file) = each %Apache::Reload::INCS) { + local $^W; + warn "Apache::Reload: Checking mtime of $key\n" if $DEBUG; + + my $mtime = (stat $file)[9]; + + unless (defined($mtime) && $mtime) { + for (@INC) { + $mtime = (stat "$_/$file")[9]; + last if defined($mtime) && $mtime; + } + } + + warn("Apache::Reload: Can't locate $file\n"),next + unless defined $mtime and $mtime; + + unless (defined $Stat{$file}) { + $Stat{$file} = $^T; + } + + if ($mtime > $Stat{$file}) { + delete $INC{$key}; + # warn "Reloading $key\n"; + if (my $symref = $UndefFields{$key}) { +# warn "undeffing fields\n"; + no strict 'refs'; + undef %{$symref}; + } + require $key; + warn("Apache::Reload: process $$ reloading $key\n") + if $DEBUG; + } + $Stat{$file} = $mtime; + } + + return 1; +} + +1; +__END__ + +=head1 NAME + +Apache::Reload - Reload changed modules + +=head1 SYNOPSIS + +In httpd.conf: + + PerlInitHandler Apache::Reload + PerlSetVar ReloadAll Off + +Then your module: + + package My::Apache::Module; + + use Apache::Reload; + + sub handler { ... } + + 1; + +=head1 DESCRIPTION + +This module is two things. First it is an adaptation of Randal +Schwartz's Stonehenge::Reload module that attempts to be a little +more intuitive and makes the usage easier. Stonehenge::Reload was +written by Randal to make specific modules reload themselves when +they changed. Unlike Apache::StatINC, Stonehenge::Reload only checked +the change time of modules that registered themselves with +Stonehenge::Reload, thus reducing stat() calls. Apache::Reload also +offers the exact same functionality as Apache::StatINC, and is thus +designed to be a drop-in replacement. Apache::Reload only checks modules +that register themselves with Apache::Reload if you explicitly turn off +the StatINC emulation method (see below). Like Apache::StatINC, +Apache::Reload must be installed as an Init Handler. + +=head2 StatINC Replacement + +To use as a StatINC replacement, simply add the following configuration +to your httpd.conf: + + PerlInitHandler Apache::Reload + +=head2 Register Modules Implicitly + +To only reload modules that have registered with Apache::Reload, +add the following to the httpd.conf: + + PerlInitHandler Apache::Reload + PerlSetVar ReloadAll Off + # ReloadAll defaults to On + +Then any modules with the line: + + use Apache::Reload; + +Will be reloaded when they change. + +=head2 Register Modules Explicitly + +You can also register modules explicitly in your httpd.conf file that +you want to be reloaded on change: + + PerlInitHandler Apache::Reload + PerlSetVar ReloadAll Off + PerlSetVar ReloadModules "My::Foo My::Bar Foo::Bar::Test" + +Note that these are split on whitespace, but the module list B +be in quotes, otherwise Apache tries to parse the parameter list. + +=head2 Special "Touch" File + +You can also set a file that you can touch() that causes the reloads to be +performed. If you set this, and don't touch() the file, the reloads don't +happen. This can be a great boon in a live environment: + + PerlSetVar ReloadTouchFile /tmp/reload_modules + +Now when you're happy with your changes, simply go to the command line and +type: + + touch /tmp/reload_modules + +And your modules will be magically reloaded on the next request. This option +works in both StatINC emulation mode and the registered modules mode. + +=head1 PSUEDOHASHES + +The short summary of this is: Don't use psuedohashes. Use an array with +constant indexes. Its faster in the general case, its more guaranteed, and +generally, it works. + +The long summary is that I've done some work to get this working with +modules that use psuedo hashes, but its still broken in the case of a +single module that contains multiple packages that all use psuedohashes. + +So don't do that. + +=head1 AUTHOR + +Matt Sergeant, matt@sergeant.org + +=head1 SEE ALSO + +Apache::StatINC, Stonehenge::Reload + +=cut