You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl-cvs@perl.apache.org by do...@apache.org on 2001/01/02 20:53:14 UTC
cvs commit: modperl-2.0/pod modperl_design.pod
dougm 01/01/02 11:53:13
Added: pod modperl_design.pod
Log:
design doc
Revision Changes Path
1.1 modperl-2.0/pod/modperl_design.pod
Index: modperl_design.pod
===================================================================
=head1 NAME
mod_perl_design - notes on the design and goals of mod_perl-2.0
=head1 SYNOPSIS
perldoc mod_perl_design
=head1 DESCRIPTION
notes on the design and goals of mod_perl-2.0
=head1 The Interpreter Pool
this logic is only enabled if Perl is built with -Dusethreads
otherwise, mod_perl will behave just as 1.xx, using a single
interpreter, which is only useful if you're using the prefork mpm.
when the server is started, a Perl interpreter is constructed, parsing
any code specified in the configuration, just as 1.xx does. this
interpreter is refered to as the "parent" interpreter. then, for
the number of PerlInterpStart configured, a (thread-safe) clone of the
parent interpreter is made (via perl_clone()) and added to a pool of
interpreters. this clone copies any writeable data (e.g. the symbol
table) and shares the compiled syntax tree. from my measurements of a
startup.pl including a few random modules:
use CGI ();
use POSIX ();
use IO ();
use SelfLoader ();
use AutoLoader ();
use B::Deparse ();
use B::Terse ();
use B ();
use B::C ();
the parent adds 6M size to the process, each clone adds less than half
that size, ~2.3M, thanks to the shared syntax tree. at request time,
if any Perl*Handlers are configured, an available interpreter is
selected from the pool. as there is a request_rec per thread, a
pointer is saved in either the conn_rec->pool or request_rec->pool,
which will be used for the lifetime of that request.
for handlers that are called when threads are not running
(PerlChild{Init,Exit}Handler), the parent interpreter is used.
several configuration parameters control the interpreter pool management:
=over 4
=item PerlInterpStart
happens at startup time, the number of intepreters to clone
=item PerlInterpMax
if all running interpreters are in use, mod_perl will clone new
interpreters to handle the request, up until this number of
interpreters is reached. when Max is reached, mod_perl will block (via
COND_WAIT()) until one becomes available (signaled via COND_SIGNAL())
=item PerlInterpMinSpare
the minimum number of available interpreters this parameter will clone
interpreters up to Max, before a request comes in
=item PerlInterpMaxSpare
mod_perl will throttle down the number of interpreters to this number
as those in use become available
=item PerlInterpMaxRequests
the maximum number of requests an interpreter should serve, the
interpreter is destroyed when the number is reached and replaced with
a fresh one.
=back
=head2 tipool
the interpreter pool is implemented in terms of a "tipool" (thread
item pool), a generic api which can be reused for other data such as
database connections.
=head2 Virtual Hosts
the interpreter management has been implemented in a way such that
each VirtualHost can have its own parent Perl interpreter and/or mip.
it is also possible to disable mod_perl for a given virtual host.
=head2 Future
at the moment, the interpreter pool is just a proof-of-concept
implementation, to test that requests can be handled concurrently.
the link-list implementation will certainly be optimized. and, some
of the interpreter pool management might be moved into it's own thread.
but the concept of mapping an interpreter clone to a thread will
likely remain.
a "garbage collector", which could also run in it's own thread,
examining the padlists of idle interpreters and deciding to release
and/or report large strings, array/hash sizes, etc., that Perl is
keeping around as an optimization.
=head1 Glue Code and Callbacks
the code for hooking mod_perl in the various phases, including
Perl*Handler directives is generated by the ModPerl::Code module.
when a mod_perl hook is called for a given phase, the glue code has an
index into the array of handlers, so it knows to return DECLINED right
away if no handlers are configured, without entering the Perl runtime
as 1.xx did. the handlers are also now stored in an
ap_array_header_t, which is might lighter and faster than using a Perl
AV, as 1.xx did. and again, keeps us out of the Perl runtime until
we're sure we need to be there.
Perl*Handlers are now "compiled", that is, the various forms of:
PerlHandler MyModule (defaults to MyModule::handler or MyModule->handler)
PerlHandler MyModule->handler
PerlHandler $MyObject->handler
PerlHandler 'sub { print "foo\n" }'
are only parsed once, unlike 1.xx which parsed everytime the handler
was used. there will also be an option to parse the handlers at
startup time. note: this feature is currently not enabled with
threads, as each clone needs its own copy of Perl structures.
a "method handler" is now specifed using the `method' sub attribute,
e.g.
sub handler : method {};
instead of 1.xx's
sub handler ($$) {}
=head1 Build System
the biggest mess in 1.xx is mod_perl's Makefile.PL, the majority of
logic has been broken down and moved to the Apache::Build module.
the Makefile.PL will construct an Apache::Build object which will have
all the info it needs to generate scripts and Makefiles that
apache-2.0 needs. regardless of what that scheme may be or change to,
it will be easy to adapt to with build logic/variables/etc divorced
from the actual Makefiles and configure scripts.
the current state of the build system is far from complete, but just
enough to build a libmodperl.a or libmodperl.so
see 00README_FIRST if you're interested in giving it a whirl.
=head1 SEE ALSO
perlguts(1), perlembed(1), perlxs(1)
=head1 AUTHOR
Doug MacEachern