Switching to mod_perl

I've been looking more and more into possibly using mod_perl to boost the speed of my Perl scripts, since I notice a definate difference in execution speed between them and PHP (such as a small delay before pages start to load under Perl). I'm assuming this is because PHP is "built into" Apache, since it has a module for it, where as Perl is still a standard CGI and executed seperately.

I'm still not quite sure about all of the little details in making a script compatible, however. Since the script is always active, I know that means I need to make sure I set values to all important variables so they can't carry on between sessions, and thought I had that and the whole running in a different directory issue well in hand at first, until switching to it on my Linode, where my software then proceeded to use up every available Mysql connection. lol. But at least it was just a simple matter of turning mod_perl back off for the time being and everything going back to normal.

So I guess I'm basically asking whether there's some kind of basic reference somewhere out there to describe the things I need to do different than a normal Perl program. Aside from the full-fledged and somewhat confusing documentation, all I've seen are small "tutorials" on certain aspects, but nothing in depth such as how to handle database connections (and how not to use them all up), the best way to initialize/re-use variables, how best to deal with the fact scripts no longer execute in the directory they exist in, and those sorts of things.

I'm also curious why Perl can't be more like PHP in the respect of just having a module loaded to prevent having to load the interpreter everytime, since mod_perl is the only thing I know of which comes close to that, except it goes farther and keeps the script in memory as well. Wouldn't one still see a performance benefit if Perl was simply more integrated with Apache?

Anyhoo, it may be getting time to move on to using PHP more often, or maybe that new Ruby on Rails I keep hearing good things about, but I've used Perl so long that I'm just comfortable working with it. So if there's any way I can get some increased performance out of it with mod_perl (or some equivalent), that'd be great. Thanks in advance!

3 Replies

@FyberOptic:

I'm also curious why Perl can't be more like PHP in the respect of just having a module loaded to prevent having to load the interpreter everytime, since mod_perl is the only thing I know of which comes close to that, except it goes farther and keeps the script in memory as well. Wouldn't one still see a performance benefit if Perl was simply more integrated with Apache?

modperl is as integrated with Apache as possible, more so than PHP, as this quote from What is modperl? explains:

> modperl is more than a scripting language. It is a unification of Apache with Perl, meaning that much of Apache can be controlled from Perl (including its configuration - meaning that configuration can be dynamic!). Although Perl can be embedded within HTML documents (through ePerl, modperl extended Server Sides Includes or other methods), mod_perl is usually used to supply the functionality that allows Apache extension modules to be written in Perl.

I don't think you can write Apache modules or httpd.conf in PHP, but if you don't need that kind of power it might fill your needs. Here are a few URLs you might find helpful:

Practical mod_perl

The mod_perl Developer's Cookbook

mod_perl 1.0 User Guide

Writing Apache Modules with Perl and C

More ways to do it:

http://www.fastcgi.com/

http://sourceforge.net/projects/speedycgi/

I run several mod_perl2 scripts on my Linode.

I agree with your critique of modperl v. PHP. It's just too hairy, and I don't think most Perl devs really need tight integration w Apache, they just accept it because modperl is by far the most mature and supported way to get persistent perl running (yes I know about fastcgi etc).

Anyway, that said, you do have some relatively easy options. The first that springs to my mind is switching from DBI->connect to DBI->connect_cached which will reuse existing DB handles. It is possible you are creating inadvertant closures and that this will not help but it likely will.

The other is to simply close your $dbh (database handle) at the end of the script with $dbh->disconnect if you are not doing so already. Under CGI, your script destroys $dbh when it goes out of scope at termination of script, and $dbh closes the DB connection. Under mod_perl, the script never actually terminates.

Why doesn't the old $dbh disconnect when the script runs again and $dbh is re-initialized? Honestly, I'm not sure, but odds are it is inside some kind of closure. If you use Apache::Registry, the whole script is stuffed inside a big sub{} so even top level lexicals (like my $dbh) end up persisting inside a particular invocation. You might try declaring $dbh as a true global ($::dbh) or as our $dbh instead of my $dbh (although my knowledge of "our" is scattershot).

Finally you may want to move the script first to Apache's PerlRun mode, which is like CGI in that all vars and connections are cleared on each invocation but like mod_perl in that you don't have to fork and load the perl interp on each request. So you pay for the DB connect but not the interp fork/load. Not sure if it has to compile the script each time.

Once you have PerlRun working you can move it to Apache::Register. You can probably leave it there. Some hard core folks go all the way to porting their scripts into Apache handlers but from what I understand you get pretty minimal performance boost for doing so.

Upon slightly more research it appears both DBI->connect_cached and the "our" operator to declar your $dbh _should_ solve your problem.

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct