On Sun, Jun 15, 2003 at 02:44:02PM +0800, Philippe M. Chiasson wrote:
[...]
> This could be related to a recently discovered bug in
> mp_preload_module(), see
> http://marc.theaimsgroup.com/?t=105532710700003&r=1&w=2
> for the original report.
> 

That is a possiblity.  I am preloading Project::Control,
but I am not preloading other modules that inherit from
it.  I am also using Apache::Reload, if that matters.  

Below is how Project::Control is setup, which
is the module/handler that most commonly exhibits the
problem.  Project::Control is a dispatcher that loads 
("require"-s) a module based on a URI to module name 
mapping hash, then calls the "run" method in that 
package.  The "require"-d module is always a subclass 
of Project::Control.pm.  The failure becomes apparent
when the $apache->status call is made because 
$apache is not an object in the failing case.

Again, this module almost always works.  It usually
only begins failing after apache has been running
for several hours, and seems to be more common under
heavy load.

*** http.conf ***:

  <Files "*.pcm">
    SetHandler perl-script
    PerlModule Project::Control
    PerlHandler Project::Control
  </Files>

*** library/Project/Control.pm ***:

  package Project::Control;
  use Apache();
  use Apache::Constants qw(:common :response REDIRECT SERVER_ERROR);
  use Apache::Reload;
  use Class::MethodMaker
    get_set => [ qw( apache ... ) ], 
    new_hash_init => '_create';


  ...

  use vars qw/%URI_MAP/;
  %URI_MAP = (
    '/uri/one' => 'Project::Control::HandleUriOne',
    ... for different URIs 
  );
  sub handler ($$) = {
    my ($class, $apache) = @_;
    Apache::request($apache);
    $apache->status(200); # sets default <*** Failure occurs here
    ...
    my $self = $class->_create(apache => $apache, ...);
    (my $uri = $apache->uri) =~ s/\.[^\.]+$//;
    my $module = $URI_MAP{$uri} or Carp::confess("Page [$uri] not installed");
    (my $path = $module) =~ s!::!/!g;
    $path .= ".pm";
    bless $self, $module;
  
    eval {
      require $path;
      $self->run( $apache );
    };

    ...

    return OK;
  }
  
  1;

*** library/Project/HandleUriOne ***:

  package Project::HandleUriOne;
  ...
  use Apache::Reload;
  use base qw( Project::Control );

  sub run {
    my $self = shift;
    ... code to generate output goes here ...
  }

  1;


> > [Fri Jun 13 06:00:06 2003] [error] Can't call method "status" on an undefin=
> > ed
> > +value at Project/Control.pm line 116.
> 
> Does this happen only once per child, or does the affected child behaves
> like that for each and every request to that handler?

It seems to happen for every request that the affected
child handles.  I don't have a test case that exercises
the problem, so I don't have real solid data on the behavior,
but it seems like once a child begins exhibiting this
erroneous behavior, it continues to do so for the rest of
its lifetime.  I am not sure whether it exhibits this
behavior from the time it is created or starts doing that
later after having successfully served other requests.

Any suggestions as to how to contruct a test case so that
I can make this problem be repeatable would be greatly
appreciated.

> One thing that can fix this problem, if it's indeed caused by
> mp_preload_module, would be to make sure to preload that module
> with a PerlModule My::Class in your httpd.conf
> 

I am preloading Project::Control, which I think would be
sufficient, but am not preloading the subclass modules that
it uses. I am not sure whether that matters or not.  
sub handler is never overridden in the subclasses. 

Thanks for your help.

--
Matthew Pressly

 


Reply via email to