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