Writing Modules for mod_perl

Discover the flexibility and power of writing mod_perl modules instead of CGI programs.

Reducing Memory Usage

mod_perl is an exciting
development that has already made a great many new applications
possible. But there is a trade-off for everything, and mod_perl's
additional functionality comes at the expense of greater memory
usage. It is hard to calculate the additional memory needed for
mod_perl, but keep in mind that Perl can be a bit of a memory
hog.

In addition, while lexical (“my” or “temporary”)
variables disappear after each invocation of a Perl module rule via
mod_perl, global variables stick around across invocations. This
can be an attractive way to keep track of state in your program,
but it can also lead to larger memory allocations.

For example, if your module creates an array with 10,000
elements, that array will continue to consume memory even after the
program is invoked. This might be useful in some cases, such as
when a complicated data structure is referenced in each invocation.
However, it also means the large structure will constantly eat up
memory, as opposed to only when necessary.

You can reduce memory usage by forcing mod_perl to share
memory among Apache child processes. When you run Apache as a web
server, it “preforks” a number of processes so that incoming
connections will not have to wait for a new server process to be
created. Each of these preforked servers is considered a separate
process by Linux, operating independently. However, Apache is smart
enough to share some memory among server siblings, at least to a
certain degree.

mod_perl takes advantage of
this shared memory by allowing the various server processes to
share Perl code as well. However, there is a catch: you must make
sure the Perl code is brought into mod_perl before preforking takes
place. Perl modules and code compiled after the split occurs will
raise the memory requirement for each individual server process,
without regard to whether the same code has been loaded by another
process.

In order to load code before Apache forks off child
processes, use the PerlModule directive in the configuration
files.

If, for example, you use the statement

PerlModule Apache::DBI

in one of the *.conf files, then

use Apache::DBI;

in a PerlHandler module, the latter invocation does not actually
load any new code. Rather, it uses the cached, shared version of
Apache::DBI that was loaded at
startup by mod_perl.

You can load multiple modules with PerlModule, using the
syntax

PerlModule Apache::DBI Apache::DBII Apache::DBIII

However, you can load only ten modules this way. If you want
to load more, you can use the PerlRequire directive. Strictly
speaking, PerlRequire allows you to specify the name of a Perl
program to be evaluated only when Apache starts up. For example,

PerlRequire /usr/local/apache/conf/startup.pl

will evaluate the contents of startup.pl before forking off Apache
child processes. However, if you include a number of “use”
statements in startup.pl, you can effectively get around
PerlModule's ten-module limit.

Remember that PerlModule or PerlRequire is necessary for
modules to be shared among the different Apache sibling server
processes, but it is not sufficient. You will still have to import
the module in your own program in order to reap the
benefits.

Conclusion

When I first started to work with mod_perl, I thought it was
useful for speeding up CGI programs and for running filters like
Embperl. As I have grown more dependent on it in my own work, I am
amazed and impressed by the power mod_perl offers programmers
looking to harness the power of Apache without the overhead of
external programs or the development time associated with C.

As you can see, writing mod_perl modules is not difficult and
is limited only by your imagination. It does require that you think
a bit more carefully about your programs than when you are working
with CGI, since you can affect the Apache server in ways that will
slow it down or otherwise hurt your system's performance.

Reuven M. Lerner
(reuven@lerner.co.il)
is an Internet and web
consultant living in Haifa, Israel, who has been using the web
since early 1993. His book Core Perl will be published
by Prentice-Hall in the spring. The ATF home page, including archives and
discussion forums, is at http://www.lerner.co.il/atf/.