📄 reload.pm
字号:
The C<*> wild character can be used to register groups of files underthe same namespace. For example the setting: PerlSetVar ReloadModules "ModPerl::* Apache2::*"will monitor all modules under the namespaces C<ModPerl::> andC<Apache2::>.=head2 Monitor Only Certain Sub DirectoriesTo reload modules only in certain directories (and theirsubdirectories) add the following to the I<httpd.conf>: PerlModule Apache2::Reload PerlInitHandler Apache2::Reload PerlSetVar ReloadDirectories "/tmp/project1 /tmp/project2"You can further narrow the list of modules to be reloaded from thechosen directories with C<ReloadModules> as in: PerlModule Apache2::Reload PerlInitHandler Apache2::Reload PerlSetVar ReloadDirectories "/tmp/project1 /tmp/project2" PerlSetVar ReloadAll Off PerlSetVar ReloadModules "MyApache2::*"In this configuration example only modules from the namespaceC<MyApache2::> found in the directories I</tmp/project1/> andI</tmp/project2/> (and their subdirectories) will be reloaded.=head2 Special "Touch" FileYou can also declare a file, which when gets C<touch(1)>ed, causes thereloads to be performed. For example if you set: PerlSetVar ReloadTouchFile /tmp/reload_modulesand don't C<touch(1)> the file I</tmp/reload_modules>, the reloadswon't happen until you go to the command line and type: % touch /tmp/reload_modulesWhen you do that, the modules that have been changed, will bemagically reloaded on the next request. This option works with anymode described before.=head2 Unregistering a moduleIn some cases, it might be necessary to explicitely stop reloadinga module. Apache2::Reload->unregister_module('Some::Module');But be carefull, since unregistering a module in this way will onlydo so for the current interpreter. This feature should be used withcare.=head1 Performance IssuesThis modules is perfectly suited for a development environment. Thoughit's possible that you would like to use it in a productionenvironment, since with C<Apache2::Reload> you don't have to restartthe server in order to reload changed modules during softwareupdates. Though this convenience comes at a price:=over=item *If the "touch" file feature is used, C<Apache2::Reload> has to stat(2)the touch file on each request, which adds a slight but most likelyinsignificant overhead to response times. Otherwise C<Apache2::Reload>will stat(2) each registered module or even worse--all modules inC<%INC>, which will significantly slow everything down.=item *Once the child process reloads the modules, the memory used by thesemodules is not shared with the parent process anymore. Therefore thememory consumption may grow significantly.=backTherefore doing a full server stop and restart is probably a bettersolution.=head1 DebugIf you aren't sure whether the modules that are supposed to bereloaded, 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 NameIf you modify modules, which don't declare their C<package>, and rely onC<Apache2::Reload> to reload them, you may encounter problems: i.e.,it'll appear as if the module wasn't reloaded when in fact itwas. This happens because when C<Apache2::Reload> C<require()>s such amodule all the global symbols end up in the C<Apache2::Reload>namespace! So the module does get reloaded and you see the compiletime errors if there are any, but the symbols don't get imported tothe right namespace. Therefore the old version of the code is running.=head2 Failing to Find a File to ReloadC<Apache2::Reload> uses C<%INC> to find the files on the filesystem. Ifan entry for a certain filepath in C<%INC> is relative,C<Apache2::Reload> will use C<@INC> to try to resolve that relativepath. Now remember that mod_perl freezes the value of C<@INC> at theserver startup, and you can modify it only for the duration of onerequest when you need to load some module which is not in on of theC<@INC> directories. So a module gets loaded, and registered inC<%INC> with a relative path. Now when C<Apache2::Reload> tries to findthat module to check whether it has been modified, it can't find sinceits directory is not in C<@INC>. So C<Apache2::Reload> will silentlyskip 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 CodeThe following problem is relevant only to registry handlers that cachethe compiled script. For example it concernsC<L<ModPerl::Registry|docs::2.0::api::ModPerl::Registry>> but notC<L<ModPerl::PerlRun|docs::2.0::api::ModPerl::PerlRun>>.=head3 The ProblemLet'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 thescript for the first time and we get the response: the color is whiteNow 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 cansee that C<My::Utils> was reloaded (look in the I<error_log>file). However the script still returns: the color is white=head3 The ExplanationEven though F<My/Utils.pm> was reloaded, C<ModPerl::Registry>'s cachedcode 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 thatthe 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 thatit'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 theexternal one.=head3 The SolutionThere 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 changethe module that it requires.=head1 Threaded MPM and Multiple Perl InterpretersIf you use C<Apache2::Reload> with a threaded MPM and multiple Perlinterpreters, the modules will be reloaded by each interpreter as theyare used, not every interpreters at once. Similar to mod_perl 1.0where each child has its own Perl interpreter, the modules arereloaded as each child is hit with a request.If a module is loaded at startup, the syntax tree of each subroutineis shared between interpreters (big win), but each subroutine has itsown padlist (where lexical my variables are stored). OnceC<Apache2::Reload> reloads a module, this sharing goes away and eachPerl interpreter will have its own copy of the syntax tree for thereloaded subroutines.=head1 Pseudo-hashesThe short summary of this is: Don't use pseudo-hashes. They aredeprecated since Perl 5.8 and are removed in 5.9.Use an array with constant indexes. Its faster in the general case,its more guaranteed, and generally, it works.The long summary is that some work has been done to get this moduleworking with modules that use pseudo-hashes, but it's still broken inthe case of a single module that contains multiple packages that alluse pseudo-hashes.So don't do that.=head1 Copyrightmod_perl 2.0 and its core modules are copyrighted underThe Apache Software License, Version 2.0.=head1 AuthorsMatt Sergeant, matt@sergeant.orgStas Bekman (porting to mod_perl 2.0)A few concepts borrowed from C<Stonehenge::Reload> by Randal Schwartzand C<Apache::StatINC> (mod_perl 1.x) by Doug MacEachern and AskBjoern Hansen.=cut
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -