How To Write mod_perl Compliant Plugins
ModPerl is one of the most popular accelerators for
CGI programs written in perl. However, the book
Practical mod_perl (924 pages) may be a bit too time consuming to read if all you want to do is to write a plugin for TWiki. So this is a first start for you.
- The Basics
- ModPerl draws its speed benefit from the fact that perl is "compiled into" the server, enabling one apache process to answer many consecutive requests. All the compilation is done only once,
die
doesn't die, and exit
doesn't exit.
So what does that mean for a plugin author? There are some simple rules:
- Use global variables for constants only. In particular, use
use vars ...
only for the stuff you already find in EmptyPlugin.
- If you absolutely must use a global variable, for example to shuffle data around between different stages of your plugin, make sure that you explicitly initialize the variable in your
initPlugin
routine. initPlugin
is called for every TWiki request.
- Don't use variables declared with
my
outside of subroutines in your module.
- Don't use circular references.
- If you really feel you need a circular reference, make sure to "break" it in one of the final handlers of your plugin. Otherwise perl's garbage collection will not be able to return all the memory.
- Don't use
BEGIN
blocks for things which need to be done for every request. There's initPlugin
for initialisation.
- Don't use
END
blocks.
- Don't use
//o
optimization for regexes if the regex contains request parameters.
- If you open files (or sockets), make sure you close them explicitly under all circumstances. Just calling
die
in case of an error isn't sufficient!
- don't open files in one handler (e.g.
beforeSaveHandler
), and then close them again in a different handler (e.g. afterSaveHandler
). TWiki may encounter an error condition, such as an access control violation, after the first handler being called that results in the second handler being ignored.
- You can reliably trap all
dies
by using the Error
module. For example:
- Use the
use strict;
pragram
use Error qw( :try );
...
sub commonTagsHandler {
...
try {
open(FILE, "<diskfile") || die "open failed $!";
doSomethingThatMightDie();
} finally {
close(FILE);
};
}
This will result in the
close
being called under all circumstances.
--
Contributors: HaraldJoerg,
CrawfordCurrie
Discussion
Thanks Harald for writing this! I linked it from the relevant
SupplementalDocuments so that people can find it easily.
On open files, a
die
is out of the control of Plugins since TWiki can do that happily anywhere in the core. Some notes on how to make sure one's handlers are closed would be helpful.
--
PeterThoeny - 28 Mar 2006
Some interesting reading
there.
--
StephaneLenclud - 08 Apr 2008
Now let's say I want to right a plug-in or possibly a
RcsFile implementation that assumes
mod_perl
is enabled. I should then be able to use global variables in my module and I can expect its value to be persistent until Apache is restarted right?
--
StephaneLenclud - 08 Apr 2008
Persistent
in that interpreter instance, yes. Other interpreter instances will have different values.
--
CrawfordCurrie - 08 Apr 2008
See also
mod_perl
overview and
coding.
--
StephaneLenclud - 10 Apr 2008