Loading ...
Sorry, an error occurred while loading the content.

Apache2::Reload problem (ModPerl::Util bug)

Expand Messages
  • Mark
    In 2.0.0, if there are heirarchical packages, and Apache2::Reload is configured to reload the parent , it blows away the children package namespaces (and
    Message 1 of 5 , May 29, 2005
    • 0 Attachment
      In 2.0.0, if there are heirarchical packages, and Apache2::Reload is
      configured to reload the 'parent', it blows away the 'children' package
      namespaces (and doesn't reload the children.) For example, if @INC has:

      Fubar.pm
      Fubar/Child.pm

      And Apache2::Reload reloads package Fubar, it blows away
      Fubar::Child::* and only reloads file Fubar.pm. Only a server
      restart can recover from this point.

      The actual unloading work is done by ModPerl::Util::unload_package(),
      whose behavior is contrary to the docs, which say:

      "unload_package()" takes care to leave sub-stashes intact while
      deleting the requested stash. So for example if "CGI" and "CGI::Carp"
      are loaded, calling "unload_package('CGI')" won't affect "CGI::Carp".


      I only partly understand how unload_package() works, but it seems to
      just iterate over symbols in the package and blow them away, without
      regard for the actual file from which the symbol was instantiated.

      I tried modifying the code to skip over symbols that correspond
      to a key in %INC, which seems logical and works correctly in my tests,
      but may not be a complete or perfect solution for reasons beyond
      my current testing/thinking. However, in my tests, it works correctly
      if either the parent package, child package, or both are modified.

      Comments/suggestions about the correctness of this patch requested.

      Thanks.


      *** ./blib/lib/ModPerl/Util.pm 2005-05-22 10:14:19.000000000 -0700
      --- /usr/lib/perl5/site_perl/5.8.5/i686-linux/ModPerl/Util.pm 2005-05-29 10:09:02.000000000 -0700
      ***************
      *** 36,55 ****
      --- 36,58 ----
      sub unload_package_pp {
      my $package = shift;
      no strict 'refs';
      my $tab = \%{ $package . '::' };

      # below we assign to a symbol first before undef'ing it, to avoid
      # nuking aliases. If we undef directly we may undef not only the
      # alias but the original function as well

      for (keys %$tab) {
      + if (my ($subpackage) = /(.*)::/) {
      + next if exists $INC{"$package/$subpackage.pm"};
      + }
      my $fullname = join '::', $package, $_;
      # code/hash/array/scalar might be imported make sure the gv
      # does not point elsewhere before undefing each
      if (%$fullname) {
      *{$fullname} = {};
      undef %$fullname;
      }
      if (@$fullname) {
      *{$fullname} = [];
      undef @$fullname;
    • Mark
      ... Correction. Ignore previous patch. It only worked one level of heirarchy. Correct patch is: ... *************** ... my $package = shift; no strict
      Message 2 of 5 , May 29, 2005
      • 0 Attachment
        Mark wrote:
        > In 2.0.0, if there are heirarchical packages, and Apache2::Reload is
        > configured to reload the 'parent', it blows away the 'children' package
        > namespaces (and doesn't reload the children.) For example, if @INC has:
        >
        > Fubar.pm
        > Fubar/Child.pm
        >
        > And Apache2::Reload reloads package Fubar, it blows away
        > Fubar::Child::* and only reloads file Fubar.pm. Only a server
        > restart can recover from this point.
        >
        > The actual unloading work is done by ModPerl::Util::unload_package(),
        > whose behavior is contrary to the docs, which say:
        >
        > "unload_package()" takes care to leave sub-stashes intact while
        > deleting the requested stash. So for example if "CGI" and "CGI::Carp"
        > are loaded, calling "unload_package('CGI')" won't affect "CGI::Carp".
        >
        >
        > I only partly understand how unload_package() works, but it seems to
        > just iterate over symbols in the package and blow them away, without
        > regard for the actual file from which the symbol was instantiated.
        >
        > I tried modifying the code to skip over symbols that correspond
        > to a key in %INC, which seems logical and works correctly in my tests,
        > but may not be a complete or perfect solution for reasons beyond
        > my current testing/thinking. However, in my tests, it works correctly
        > if either the parent package, child package, or both are modified.
        >
        > Comments/suggestions about the correctness of this patch requested.

        Correction. Ignore previous patch. It only worked one level of
        heirarchy. Correct patch is:

        *** ./blib/lib/ModPerl/Util.pm 2005-05-22 10:14:19.000000000 -0700
        --- /usr/lib/perl5/site_perl/5.8.5/i686-linux/ModPerl/Util.pm 2005-05-29 10:47:37.000000000 -0700
        ***************
        *** 37,56 ****
        --- 37,61 ----
        my $package = shift;
        no strict 'refs';
        my $tab = \%{ $package . '::' };

        # below we assign to a symbol first before undef'ing it, to avoid
        # nuking aliases. If we undef directly we may undef not only the
        # alias but the original function as well

        for (keys %$tab) {
        my $fullname = join '::', $package, $_;
        + if (my ($subpackage) = $fullname =~ /(.*)::/) {
        + $subpackage =~ s[::][/]g;
        + $subpackage .= ".pm";
        + next if exists $INC{$subpackage};
        + }
        # code/hash/array/scalar might be imported make sure the gv
        # does not point elsewhere before undefing each
        if (%$fullname) {
        *{$fullname} = {};
        undef %$fullname;
        }
        if (@$fullname) {
        *{$fullname} = [];
        undef @$fullname;
        }
      • Foo Ji-Haw
        Hello Mark, I have the same problem as well, though I don t have a decent solution/ workaround for it. All I ended up doing was to use the subpackages. And
        Message 3 of 5 , May 29, 2005
        • 0 Attachment
          Hello Mark,

          I have the same problem as well, though I don't have a decent solution/
          workaround for it. All I ended up doing was to use the subpackages. And
          when the subpackage changes, I touch the main package as well. That
          seems to cause Apache to reload.

          Mark wrote:

          > In 2.0.0, if there are heirarchical packages, and Apache2::Reload is
          > configured to reload the 'parent', it blows away the 'children' package
          > namespaces (and doesn't reload the children.) For example, if @INC has:
          >
          > Fubar.pm
          > Fubar/Child.pm
          >
          > And Apache2::Reload reloads package Fubar, it blows away
          > Fubar::Child::* and only reloads file Fubar.pm. Only a server
          > restart can recover from this point.
          >
          > The actual unloading work is done by ModPerl::Util::unload_package(),
          > whose behavior is contrary to the docs, which say:
          >
          > "unload_package()" takes care to leave sub-stashes intact while
          > deleting the requested stash. So for example if "CGI" and "CGI::Carp"
          > are loaded, calling "unload_package('CGI')" won't affect "CGI::Carp".
          >
          >
          > I only partly understand how unload_package() works, but it seems to
          > just iterate over symbols in the package and blow them away, without
          > regard for the actual file from which the symbol was instantiated.
          >
          > I tried modifying the code to skip over symbols that correspond
          > to a key in %INC, which seems logical and works correctly in my tests,
          > but may not be a complete or perfect solution for reasons beyond
          > my current testing/thinking. However, in my tests, it works correctly
          > if either the parent package, child package, or both are modified.
          >
          > Comments/suggestions about the correctness of this patch requested.
          >
          > Thanks.
          >
          >
          > *** ./blib/lib/ModPerl/Util.pm 2005-05-22 10:14:19.000000000 -0700
          > --- /usr/lib/perl5/site_perl/5.8.5/i686-linux/ModPerl/Util.pm
          > 2005-05-29 10:09:02.000000000 -0700
          > ***************
          > *** 36,55 ****
          > --- 36,58 ----
          > sub unload_package_pp {
          > my $package = shift;
          > no strict 'refs';
          > my $tab = \%{ $package . '::' };
          >
          > # below we assign to a symbol first before undef'ing it, to avoid
          > # nuking aliases. If we undef directly we may undef not only the
          > # alias but the original function as well
          >
          > for (keys %$tab) {
          > + if (my ($subpackage) = /(.*)::/) {
          > + next if exists $INC{"$package/$subpackage.pm"};
          > + }
          > my $fullname = join '::', $package, $_;
          > # code/hash/array/scalar might be imported make sure the gv
          > # does not point elsewhere before undefing each
          > if (%$fullname) {
          > *{$fullname} = {};
          > undef %$fullname;
          > }
          > if (@$fullname) {
          > *{$fullname} = [];
          > undef @$fullname;
          >
        • Philippe M. Chiasson
          ... This is clearly a bug. ... Yup, it s that simple and there is a slightly smarter version in XS that does check the source of the symbols from. ... Much
          Message 4 of 5 , Jun 1, 2005
          • 0 Attachment
            Mark wrote:
            > Mark wrote:
            >
            >> In 2.0.0, if there are heirarchical packages, and Apache2::Reload is
            >> configured to reload the 'parent', it blows away the 'children' package
            >> namespaces (and doesn't reload the children.) For example, if @INC has:
            >>
            >> Fubar.pm
            >> Fubar/Child.pm
            >>
            >> And Apache2::Reload reloads package Fubar, it blows away
            >> Fubar::Child::* and only reloads file Fubar.pm. Only a server
            >> restart can recover from this point.
            >>
            >> The actual unloading work is done by ModPerl::Util::unload_package(),
            >> whose behavior is contrary to the docs, which say:
            >>
            >> "unload_package()" takes care to leave sub-stashes intact while
            >> deleting the requested stash. So for example if "CGI" and "CGI::Carp"
            >> are loaded, calling "unload_package('CGI')" won't affect "CGI::Carp".

            This is clearly a bug.

            >> I only partly understand how unload_package() works, but it seems to
            >> just iterate over symbols in the package and blow them away, without
            >> regard for the actual file from which the symbol was instantiated.

            Yup, it's that simple and there is a slightly smarter version in XS
            that does check the source of the symbols from.

            >> I tried modifying the code to skip over symbols that correspond
            >> to a key in %INC, which seems logical and works correctly in my tests,
            >> but may not be a complete or perfect solution for reasons beyond
            >> my current testing/thinking. However, in my tests, it works correctly
            >> if either the parent package, child package, or both are modified.
            >>
            >> Comments/suggestions about the correctness of this patch requested.
            >
            > Correction. Ignore previous patch. It only worked one level of
            > heirarchy. Correct patch is:

            Much simpler patch to just skip stashes has been checked in in rev 179448.

            If you can try latest-svn and confirm your problem goes away, that would be
            fantastic.

            --------------------------------------------------------------------------------
            Philippe M. Chiasson m/gozer\@(apache|cpan|ectoplasm)\.org/ GPG KeyID : 88C3A5A5
            http://gozer.ectoplasm.org/ F9BF E0C2 480E 7680 1AE5 3631 CB32 A107 88C3A5A5
          • Mark
            ... That works. Thanks.
            Message 5 of 5 , Jun 5, 2005
            • 0 Attachment
              Philippe M. Chiasson wrote:
              > Mark wrote:
              >
              >>Mark wrote:
              >>
              >>
              >>>In 2.0.0, if there are heirarchical packages, and Apache2::Reload is
              >>>configured to reload the 'parent', it blows away the 'children' package
              >>>namespaces (and doesn't reload the children.) For example, if @INC has:
              >>>
              >>>Fubar.pm
              >>>Fubar/Child.pm
              >>>
              >>>And Apache2::Reload reloads package Fubar, it blows away
              >>>Fubar::Child::* and only reloads file Fubar.pm. Only a server
              >>>restart can recover from this point.
              >>>
              >>>The actual unloading work is done by ModPerl::Util::unload_package(),
              >>>whose behavior is contrary to the docs, which say:
              >>>
              >>> "unload_package()" takes care to leave sub-stashes intact while
              >>> deleting the requested stash. So for example if "CGI" and "CGI::Carp"
              >>> are loaded, calling "unload_package('CGI')" won't affect "CGI::Carp".
              >
              >
              > This is clearly a bug.
              >
              >
              >>>I only partly understand how unload_package() works, but it seems to
              >>>just iterate over symbols in the package and blow them away, without
              >>>regard for the actual file from which the symbol was instantiated.
              >
              >
              > Yup, it's that simple and there is a slightly smarter version in XS
              > that does check the source of the symbols from.
              >
              >
              >>>I tried modifying the code to skip over symbols that correspond
              >>>to a key in %INC, which seems logical and works correctly in my tests,
              >>>but may not be a complete or perfect solution for reasons beyond
              >>>my current testing/thinking. However, in my tests, it works correctly
              >>>if either the parent package, child package, or both are modified.
              >>>
              >>>Comments/suggestions about the correctness of this patch requested.
              >>
              >>Correction. Ignore previous patch. It only worked one level of
              >>heirarchy. Correct patch is:
              >
              >
              > Much simpler patch to just skip stashes has been checked in in rev 179448.
              >
              > If you can try latest-svn and confirm your problem goes away, that would be
              > fantastic.

              That works. Thanks.
            Your message has been successfully submitted and would be delivered to recipients shortly.