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

Reply via email to