On Fri, 7 Sep 2001, Barrie Slaymaker wrote:

> On Fri, Sep 07, 2001 at 04:56:30PM +0800, Stas Bekman wrote:
> > 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:
>
>
> Or the repurposed <Perl>?

Yup, that's exactly why I came up with this idea :0)

> >   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
> >   });
>
> Howabout custom directives, so no startup.pl needed, and can use
> different settings in different <Location>, <Directory>, <Proxy>,
> whatever (these 4 correspond to your 4 examples, playing the name game a
> bit):
>
>    PerlRegistryPackage    MyCoolRegistry
>    PerlRegistryKeyAlg     filename
>    PerlRegistryAutoReload 1
>    PerlRegistryFlush      0

That won't be a problem. We can provide 3 different ways to cook packages:

1. manually crafting the package.
2. via cook() API.
3. via custom directives.

> Hmmm, also might want to allow key_alg/PerlRegistryKeyAlg to take a
> handler spec:
>
>    PerlRegistryKeyAlg     My::NameSpaceGenerator
>
> These would all be read by Apache::Registry::handler().  I don't think
> we need a new class cooked up for each of these, that seems likely to be
> too confusing.

It won't be too confusing for most of the people since they will just use
Apache::Registry or Apache::PerlRun as before, without even knowing that
these are not real modules anymore.

> What's more important to me is controlling the parameters of
> Apache::Registry, or subclassing it when I get too far away from it's
> noremal capabilities.

You should be able to subclass the resulting packages.

> For instance, setting root of the namespace the script/handler is
> compiled in to and the algorithm used to generate the relative part of
> the namespace should be able to be set by a parameter.  That might be
> configured using perlish interpolation:
>
>     PerlRegistryNameSpace MyRegistryRoot::${filename}
>
> where $filename/$inode/$uri/$vh is escaped to be a nice package name.
> This leads to the natural
>
>     PerlRegistryNameSpace MyRegistryRoot::${vh}::${filename}
>
> and the slightly unnatural:
>
>     PerlRegistryNameSpace MyRegistryRoot::&{My::key_generating_sub}
>
> or:
>
>     PerlRegistryNameSpace &{My::key_generating_sub}
>
> to allow some subroutine to be called to generate the name.

I think that all directives in httpd.conf or cook() should accept a
reference to a sub, so you can write any sub anywhere and use it. One of
the most important benefits of it is using NOPs.

package Foo;
use constant NOP => sub {};

now is it really getting optimized away at compile time? Or is there some
better way to make NOP CODE reference?

and then saying:

PerlRegistryDoStat Foo::NOP

to skip the stat() call.

So when handler() calls do_stat, it'll be optimized away at compile time.
Am I on the right track?

> It'd be nice if the new Apache::Registry could use or just cooperate
> with Apache::Reload for autostat/autoreload.

That won't really work. Because the files on the disk aren't the same as
registry packages, unless Apache::Reload will try to use a known interface
to package_reload in the registry space, but I see no why how
Apache::Reload will figure out what registry package in %INC belongs to
what Apache::RegistryFoo module.

> Other nice-to-have (IMHO) features
>
>    - Allowing a special token in a script like ##__REGISTRY_HANDLER__
>      that could be used when porting CGI scripts to move all "my" decls
>      above, so that a script could be partitioned in to globals and
>      handler code without having to rewrite as a handler.  Perhaps the
>      above template could be modified like so:
>
>       package <%= $package_name %> ;
>
>       ##...
>
>       <%= $script_globals_section %>
>
>       ##...
>
>       sub handler {
>           my ( $r ) = Apache::Request->new( shift ) ;
>       #line 1 <%= $script_file_name %>
>           {<%= $script_body_section %>} ;
>           return OK ;
>       }
>
>       1 ;
>
>      Then, porting a script containing named subs could be "tweaked"
>      by adding a comment to it like so:
>
>       use CGI ;
>       use DBI ;
>       use strict ;
>
>       my $rows ;
>       my $dbh = ... ;
>
>       sub emit_row {
>           ++$rows ;
>           print tr( map td, @_, ), "\n" ;
>       }
>
>       ##__REGISTRY_HANDLER__ (for Apache::Registry operation)
>
>       print start_html ;
>       print "<table>" ;
>       print_row( @$_ ) for $dbh->selectall_arrayref(...) ;
>       print "</table>" ;
>       print "$rows served\n" ;
>
>       that might help cgi->registry porters.  Only the last 5 statements
>       would end up in the handler().  Could also have other special tags
>       to defer some code to a cleanup handler, but you gotta stop
>       somewhere.

Hmm, that's an interesting idea. But won't it confuse users even more?
this will require them to move all the none-handler code up, or we need
something like: ##__REGISTRY_HANDLER_END__ as well.

this custom parse() function can be always provided and used if wanted
instead of the default one, rather than complicating the parsing of the
default sub.

>    - A source filter, to allow burgeoning young mod_perl hackers to
>      develop their radical new idea (ie a new templating system) easily.
>      This is probably best done as an overridable method like
>      parse_source().  The base class parse_source would (in my perfect,
>      little world) parse the source for the ##__BEGIN__HANDLER, __END__,
>      __DATA__, etc. tokens and pass the resulting chunks to the little
>      templating engine needed to do the following...

Yup, just like your previous idea. write your own parse_source() and do
whatever you want.

>    - specify the module file generated from a script as a subroutine
>      template file, so I/you/we could define an application-specific
>      template like (borrowing ASP tags here):
>
>         package <%= $package_name %> ;
>
>         use strict ; ## or not...
>       use My::Standard::Lib ;
>       use Apache::Util ;
>       use Apache::File ;
>       use Apache::Constant ;
>       use My::Application::Lib ;
>       use GD ;
>
>       *dbh = *My::Globals::dbh ;
>
>       ## etc., etc.
>
>       use base qw( My::AppBase ) ;
>
>         ## Some little utility routines...
>       sub empty { ! defined $_[0] || ! length $_[0] }
>       ## etc.
>
>       sub handler {
>           my ( $r ) = Apache::Request->new( shift ) ;
>         #line 1 <%= $script_file_name %>
>           {<%= $script_body %>} ;
>           return OK ;
>       }
>
>       1 ;
>
>      This could be done a little less clearly by using a overloadable
>      Apache::Registry method to return the source code to be eval()ed,
>      but lately I've been finding that templates work their magic when
>      writing Perl and C code generators just as well as when writing
>      HTML or RTF code generators.  For instance, you could easily call
>      $r->dir_config in your nifty little registry module template. Don't
>      want to start a debate on tempalting engines though, so just being
>      able to override a method to convert script source code in to
>      handler() module source code would be nice.

:) this will be possible as well.

> This would turn Apache::Registry in to a templating system backend
> and/or a custom application framework, whereby I could use Perl files
> ("scripts") instead of template files.

Yup. Also check Apache::Template!

Thanks for the useful comments, Barrie

I'd like to hear more ideas about solving the closure problem (in addition
to the one you've suggested with ##__APACHE__HANLER__.

_____________________________________________________________________
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