Malcolm wrote:
On Friday 22 February 2008 02:14:43 pm Jeremy Blain wrote:
This is a mod_perl issue, not mason.
The apache module is loaded once, and not recompiled (one of the main
ways mod_perl increases performance).
I think there are some modules that allow it to dynamically reload when
needed, a search of the mod_perl lists
may help.
Apache::Reload is what you're looking for.
However it is *not* recommended for production, just for development. As it
has to edit the perl symbol table it's not completely safe and may break
certain code (and you also lose any benefit of preloading modules).
I've never used Apache::Reload and it looks like it might be a good
shortcut. Here's the massive hack that I have in my top level autohandler:
eval {
$WebLib = Web::Core->new({conf => \%conf})
or die "Unable to obtain a reference for the Web function
library Web::Core $@";
$WebLib->export();
};
if ($@) {
die "autohandler error with Web::Core - $@";
}
# load Web::Core for each request when in dev
if (Web::Core::DEVSERVER) {
my @failure_reasons;
if ($conf{developer}) {
my $Web_Core_file =
"/home/www/$conf{developer}/code/lib/Web/Core.pm";
if (-f $Web_Core_file) {
# When we reload Core.pm we don't want to see complaints about
# uninitialized values and redefined subroutines just in this
section
#
# no warnings qw(uninitialized); works for uninitialized values,
# but there is no equivalent for redefined subroutines (study
perldoc
# perlsub closely to see why)
#
# so we install our own warn handler and filter out these
warnings.
# the warn handler captures the output and appends it to a string,
# but it doesn't report the warning itself by calling warn
directly
# because our caller may have a WARN handler installed. In that
# case we would call a warn handler from within a warn handler
which
# Perl doesn't allow. So our handler merely collects the warnings
# and they are reported after our warn handler has exited.
my $warnings;
my @warn_stack;
{
# set aside the caller's warn handler;
push @warn_stack, $SIG{__WARN__};
local %SIG;
$SIG{__WARN__}
= sub { my $warning = shift;
unless (
$warning =~ m/^Constant subroutine .* redefined/
|| $warning =~ m{uninitialized .+ line \d+\.$}
) {
$warnings .= $warning;
}
};
# using "do" instead of "require" because require
# won't load a file that's already loaded
undef $!;
unless (do $Web_Core_file) {
# if do cannot compile
if ($@) {
push @failure_reasons, "Compilation error in file
$Web_Core_file: $@";
}
# if do cannot find the file
# or if it couldn't compile due
# to an IO Error
if ($!) {
push @failure_reasons, "IO Error accessing
$Web_Core_file: $!";
}
# If neither error flag is set
unless (@failure_reasons) {
push @failure_reasons, "Unknown error";
}
}
# reinstall the caller's warn handler;
$SIG{__WARN__} = pop @warn_stack;
}
# now report any warnings that may have been collected.
if ($warnings) {
warn $warnings;
}
}
else {
push @failure_reasons, "Developer version `$Web_Core_file`
does not exist";
}
my $newWebLib;
eval {
$newWebLib = Web::Core->new({conf => \%conf})
or push @failure_reasons, "Unable to obtain a reference for
the Web function library Web::Core $@";
$newWebLib->export();
$WebLib = $newWebLib;
};
if ($@) {
push @failure_reasons, "Problems initializing new WebLib
object: $@";
}
}
else {
push @failure_reasons, "Developer not set";
}
if (@failure_reasons) {
warn "Unable to re-load Web::Core:\n\t"
. join("\n\t", @failure_reasons);
}
}
It's a doozy but it helps when on the shared dev server because our
developers all share the same apache processes and it's inconvenient to
restart the server all the time.
-- Ben
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Mason-users mailing list
Mason-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mason-users