Apache-Reload
view release on metacpan or search on metacpan
lib/Apache2/Reload.pm view on Meta::CPAN
that module to check whether it has been modified, it can't find since
its directory is not in C<@INC>. So C<Apache2::Reload> will silently
skip that module.
You can enable the C<Debug|/Debug> mode to see what C<Apache2::Reload>
does behind the scenes.
=head2 Problems with Scripts Running with Registry Handlers that Cache the Code
The following problem is relevant only to registry handlers that cache
the compiled script. For example it concerns
C<L<ModPerl::Registry|docs::2.0::api::ModPerl::Registry>> but not
C<L<ModPerl::PerlRun|docs::2.0::api::ModPerl::PerlRun>>.
=head3 The Problem
Let's say that there is a module C<My::Utils>:
#file:My/Utils.pm
#----------------
package My::Utils;
BEGIN { warn __PACKAGE__ , " was reloaded\n" }
use base qw(Exporter);
@EXPORT = qw(colour);
sub colour { "white" }
1;
And a registry script F<test.pl>:
#file:test.pl
#------------
use My::Utils;
print "Content-type: text/plain\n\n";
print "the color is " . colour();
Assuming that the server is running in a single mode, we request the
script for the first time and we get the response:
the color is white
Now we change F<My/Utils.pm>:
- sub colour { "white" }
+ sub colour { "red" }
And issue the request again. C<Apache2::Reload> does its job and we can
see that C<My::Utils> was reloaded (look in the I<error_log>
file). However the script still returns:
the color is white
=head3 The Explanation
Even though F<My/Utils.pm> was reloaded, C<ModPerl::Registry>'s cached
code won't run 'C<use My::Utils;>' again (since it happens only once,
i.e. during the compile time). Therefore the script doesn't know that
the subroutine reference has been changed.
This is easy to verify. Let's change the script to be:
#file:test.pl
#------------
use My::Utils;
print "Content-type: text/plain\n\n";
my $sub_int = \&colour;
my $sub_ext = \&My::Utils::colour;
print "int $sub_int\n";
print "ext $sub_ext\n";
Issue a request, you will see something similar to:
int CODE(0x8510af8)
ext CODE(0x8510af8)
As you can see both point to the same CODE reference (meaning that
it's the same symbol). After modifying F<My/Utils.pm> again:
- sub colour { "red" }
+ sub colour { "blue" }
and calling the script on the secondnd time, we get:
int CODE(0x8510af8)
ext CODE(0x851112c)
You can see that the internal CODE reference is not the same as the
external one.
=head3 The Solution
There are two solutions to this problem:
Solution 1: replace C<use()> with an explicit C<require()> +
C<import()>.
- use My::Utils;
+ require My::Utils; My::Utils->import();
now the changed functions will be reimported on every request.
Solution 2: remember to touch the script itself every time you change
the module that it requires.
=head1 Threaded MPM and Multiple Perl Interpreters
If you use C<Apache2::Reload> with a threaded MPM and multiple Perl
interpreters, the modules will be reloaded by each interpreter as they
are used, not every interpreters at once. Similar to mod_perl 1.0
where each child has its own Perl interpreter, the modules are
reloaded as each child is hit with a request.
If a module is loaded at startup, the syntax tree of each subroutine
is shared between interpreters (big win), but each subroutine has its
own padlist (where lexical my variables are stored). Once
C<Apache2::Reload> reloads a module, this sharing goes away and each
Perl interpreter will have its own copy of the syntax tree for the
reloaded subroutines.
( run in 2.985 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )