You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Andy Wardley <ab...@cre.canon.co.uk> on 2000/11/06 15:07:24 UTC

Problems with SERVER_MERGE and DIR_MERGE

I've been playing around with SERVER_CREATE, SERVER_MERGE, DIR_CREATE and
DIR_MERGE and having some mixed success.

The first problem I encountered was that my *_MERGE methods were being
ignored.  The $class->can('DIR_MERGE') and $class->can('SERVER_MERGE')
tests in the Apache::ExtUtils xs_cmd_table() sub were failing because
my methods weren't visible to the Makefile.PL.  In the short term, I
resolved this by adding

   require './Template.pm';	    # Apache::Template module

to the top of my Makefile.PL.  A closer inspection revealed the
underlying problem.  The command_table() sub does the following to
load the main module file:

    eval {
	require "$file.pm"; # so we can see the prototypes
    };
    # goes on to look in other places, but not '.'

The problem is (in this case) that the require() is loading the
Template.pm module from my regular Perl library directory, rather than
the local copy which is actually Apache::Template.  I guess there
should be a 'use lib qw(.)' or even 'require "./$file.pm"' in there
instead?

Having got the subs recognised, I'm now seeing some weird results in the
order in which the subs are being called.  Here's the relevant fragment
from my httpd.conf file:

  PerlModule        Apache::Template
  TT_IncludePath    /home/apache/tt2
  TT_PreChomp       On

  <Location /tt>
    TT_PreChomp     Off
    SetHandler	    perl-script
    PerlHandler     Apache::Template
  </Location>

My CREATE/MERGE subs (after much stripping and adding of debug code) look
like this:

  sub SERVER_CREATE {
      my $class = shift;
      my $cfg   = bless { }, $class;
      print STDERR "SERVER_CREATE($class) => $cfg\n";
      bless $cfg, $class;}

  sub SERVER_MERGE {
      my ($parent, $config) = @_;
      warn "SERVER_MERGE($parent, $config)\n";
      bless { %$parent, %$config }, __PACKAGE__;
  }

  sub DIR_CREATE {
      my $class = shift;
      my $cfg = bless { }, $class;
      print STDERR "DIR_CREATE($class) => $cfg\n";
      $cfg;
  }

  sub DIR_MERGE {
      my ($parent, $config) = @_;
      warn "DIR_MERGE($parent, $config) (", $count++, ")\n";
      bless { %$parent, %$config }, __PACKAGE__;
  }

When I fire up the server, I see the following (note the additional
debug lines generated by my TT_* config handlers)

  DIR_CREATE(Apache::Template) => Apache::Template=HASH(0x81ed0ac)
  SERVER_CREATE(Apache::Template) => Apache::Template=HASH(0x81f76b8)
  TT_IncludePath [Apache::Template=HASH(0x81ed0ac)] [/home/apache/tt2]
  TT_PreChomp [Apache::Template=HASH(0x81ed0ac)] [1]
  DIR_CREATE(Apache::Template) => Apache::Template=HASH(0x8202fd8)
  TT_PreChomp [Apache::Template=HASH(0x8202fd8)] [0]

I'm not sure why the DIR_CREATE is being called before the SERVER_CREATE.
The book (and intuition, that dangerous master) seems to imply that
SERVER_CREATE should be created first.  If I add a VirtualHost as such

  <VirtualHost _default_:*>
      TT_IncludePath /foo/zzz
  </VirtualHost>

Then I see the following (with some line breaks added):

  DIR_CREATE(Apache::Template) => Apache::Template=HASH(0x81ed0ac)
  SERVER_CREATE(Apache::Template) => Apache::Template=HASH(0x81f76b8)
  TT_IncludePath [Apache::Template=HASH(0x81ed0ac)] [/home/apache/tt2]
  TT_PreChomp [Apache::Template=HASH(0x81ed0ac)] [1]
  DIR_CREATE(Apache::Template) => Apache::Template=HASH(0x8202de0)
  TT_PreChomp [Apache::Template=HASH(0x8202de0)] [0]
  DIR_CREATE(Apache::Template) => Apache::Template=HASH(0x8202eb8)
  SERVER_CREATE(Apache::Template) => Apache::Template=HASH(0x8202ed0)
  TT_IncludePath [Apache::Template=HASH(0x8202eb8)] [/foo/zzz]
  SERVER_MERGE(Apache::Template=HASH(0x81f76b8),
	       Apache::Template=HASH(0x8202ed0))
  DIR_MERGE(Apache::Template=HASH(0x81ed0ac),
            Apache::Template=HASH(0x8202eb8))

I'm getting an additional:

  DIR_CREATE
  SERVER_CREATE
  SERVER_MERGE
  DIR_MERGE

Which again seems rather strange.  Why the DIR_CREATE and DIR_MERGE?

Then, when I service a request from /tt/* I see not one, but two DIR_MERGE:

  DIR_MERGE(Apache::Template=HASH(0x8203164),
            Apache::Template=HASH(0x8203170))
  DIR_MERGE(Apache::Template=HASH(0x8203164),
            Apache::Template=HASH(0x8203170))

Can anyone explain to me what's going on?  It differs from what I'm expecting
in the following ways:

at startup:
  DIR_CREATE gets called before a SERVER_CREATE
  DIR_MERGE gets called after any SERVER_MERGE

on request:
  DIR_MERGE gets called twice

It's entirely plausable that all this is supposed to happen, but I can't
seem to make it correspond to what the book seems to tell me should happen.
Can anyone confirm that it's unexpected behaviour, or otherwise set me
straight about what's going on?

Naturally, I've checked all the documentation, FAQ's etc. that I can find
and am still none the wiser.  If there's something that I've missed then
I'd appreciate a pointer to the right clues.  I haven't gone through the
source in detail, other than finding the relevant point in mod_perl.c and
perl_config.c where the subs are being called, but it's not immediately
apparent as to where they're being called from.


Cheers
A









-- 
Andy Wardley <ab...@kfs.org>   Signature regenerating.  Please remain seated.
     <ab...@cre.canon.co.uk>   For a good time: http://www.kfs.org/~abw/