Apache-Reload
view release on metacpan or search on metacpan
lib/Apache2/Reload.pm view on Meta::CPAN
=item *
Once the child process reloads the modules, the memory used by these
modules is not shared with the parent process anymore. Therefore the
memory consumption may grow significantly.
=back
Therefore doing a full server stop and restart is probably a better
solution.
=head1 Debug
If you aren't sure whether the modules that are supposed to be
reloaded, are actually getting reloaded, turn the debug mode on:
PerlSetVar ReloadDebug On
=head1 Caveats
=head2 Problems With Reloading Modules Which Do Not Declare Their Package Name
If you modify modules, which don't declare their C<package>, and rely on
C<Apache2::Reload> to reload them, you may encounter problems: i.e.,
it'll appear as if the module wasn't reloaded when in fact it
was. This happens because when C<Apache2::Reload> C<require()>s such a
module all the global symbols end up in the C<Apache2::Reload>
namespace! So the module does get reloaded and you see the compile
time errors if there are any, but the symbols don't get imported to
the right namespace. Therefore the old version of the code is running.
=head2 Failing to Find a File to Reload
C<Apache2::Reload> uses C<%INC> to find the files on the filesystem. If
an entry for a certain filepath in C<%INC> is relative,
C<Apache2::Reload> will use C<@INC> to try to resolve that relative
path. Now remember that mod_perl freezes the value of C<@INC> at the
server startup, and you can modify it only for the duration of one
request when you need to load some module which is not in on of the
C<@INC> directories. So a module gets loaded, and registered in
C<%INC> with a relative path. Now when C<Apache2::Reload> tries to find
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:
( run in 1.938 second using v1.01-cache-2.11-cpan-d7a12ab2c7f )