This is a proposal paper for Apache::Registry for mod_perl 2.0.

The whole family of Apache::Registry-like modules can be transformed
from hardcoded packages with specified functionality into a what I
call Apache::Registry::Cooker packages.

Since various users will want various behavior from various registry
modules, it'll be too cumbersome to create and maintain all possible
variations. Of course this could be implemented as a sub-classable
system, where users wishing their own behavior, need to subclass
whichever existing module whose behavior is the closest to the desired
one. I believe that compiling the registry package on the fly will
make things more flexible.

So I suggest the following spec:

Apache::Registry::Cooker - cook the desired registry handler.

e.g. put in startup.pl:

  use Apache::Registry::Cooker;
  Apache::Registry::Cooker::cook
  ({
    package  => 'MyCoolRegistry',
    key_alg  => 'filename', # (or inode, or uri, or vh+uri, ...)
    stat_src => 1, (0 not to stat on each request)
    flush    => 0, # flush namespace on each request
    ... # more features to come
  });

In httpd.conf you just write:

  PerlHandler MyCoolRegistry;

The cooker will do something like the following:

  use Apache::Registry::Base ();

  sub cook{
      my $cook = shift;

      my $package  = $cook->{package}  or die "package is not specified";
      my $debug    = $cook->{debug}    || 0;
      my $stat_src = $cook->{stat_src} || 0;
      my $key_alg_sub = $Apache::Registry::Base::algs{$cook->{key_alg}};

      my $package_code = << "EOP";
   package $package;

   use constant DEBUG    => $debug;
   use constant STAT_SRC => $stat_src;

   *handler  = *Apache::Registry::Base::handler{CODE};
   *sub_wrap = *Apache::Registry::Base::sub_wrap_def{CODE};
   *sub_package_name = $key_alg_sub\{CODE};

  1;
  EOP
      eval $package_code;
  }

As you can see it generates a package with the name provided by user,
and autovivify the package with requested features, by aliasing the
methods in this new package to the base of existing components, which
can be implemented in Perl or XS.

Now since we want to keep the old names with their predefined behavior
around, it's very easy. e.g. take Apache::PerlRun

  package Apache::PerlRun;

  Apache::Registry::Cooker::cook
  (
    package  => 'Apache::PerlRun',
    key_alg  => 'uri', # (or inode, or uri, or vh+uri, ...)
    stat_src => 1, (0 not to stat on each request)
    flush    => 1, # flush namespace on each request
  );
  1;

Now to use it you just do:

  PerlModule Apache::PerlRun
  <Location /dirty>
      ..
      PerlHandler Apache::PerlRun
  </Location>

Now Apache::Registry::Cooker may use many packages which specialize in
something specific, for example Apache::Registry::Flush will
concentrate on namespace flushing. This will allow us nice separation
of various functionalities in various packages.

Now about debug mode, each package may define debug code, which via
cook() interface may be enabled at compile time, so you can see
various status dumps in error_log. Since we don't want debug code to
slow down run time, this all has to be done via constants, which means
that if you enable debugging for one function it'll be enabled for all
cooked packages that use this function (in this function).

The code will try to use as many constants as possible to make the
code as optimizes as possible. Obviously for the best performance the
registry packages are to be cooked at the server startup.

Once the basic Perl components are written we can start working on XS
replacements for these components.

But the first step is to write (port) a modular Apache::Registry as we
know it today with 1.x, make it work with 2.x. This is something that
I'm going to start with.

Problems that existed in Registry modules in mod_perl 1.x that need to
be solved:

* __DATA__ and __END__ tokens: should read the file till these tokens
  are met and compile only the code that has been read so far.

* the issue with closures: Should we try to solve it or keep on
  explaining the problem? You input is welcome. If you think we should
  solve it please suggest how.

* global variables persistance: I suggest to have the cooker option to
  flash only globals at the end of each request. Of course this
  extends only to the autogenerated package, and not modules used out
  of this package.

* compiled regex with /o problem: leave it as is or handle it?

* probably need to try to handle the problem with libs collisions as
  explained here:
http://perl.apache.org/guide/porting.html#Name_collisions_with_Modules_and
Not sure yet how to do that.

* It's a known kludge with mod_perl scripts when you use a script
  coming from mod_cgi which uses -M for file comparisons, but is not
  aware of the fact that $^T is not getting reset on each request. So
  may be the cooker should have an option to reset $^T if requested.

* any other issues to solve?




_____________________________________________________________________
Stas Bekman              JAm_pH     --   Just Another mod_perl Hacker
http://stason.org/       mod_perl Guide  http://perl.apache.org/guide
mailto:[EMAIL PROTECTED]   http://apachetoday.com http://eXtropia.com/
http://singlesheaven.com http://perl.apache.org http://perlmonth.com/



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to