In addition to embedding the Perl interpreter into the Apache process, one of the really big reasons you can get such a large speed increase is because you only have to load and compile your scripts and the modules they use once for the life of the Apache process if you use Apache::Registry (the most common method of running CGIish applications under mod_perl). You do need to make sure your programs will work ok being run this way, for the most part if they'll run under use strict; you'll be okay.
Even if you can't get your scripts to run that way (for instance if you have to get a large bunch of Perl4 code working under mod_perl) you can still take advantage of the embedded Perl interpreter by using Apache::PerlRun. There's more information over at the mod_perl documentation site and I'd particularly recommend reading the porting to mod_perl guide which spells out most of the differences between writing scripts for CGI execution and for execution under mod_perl.
| [reply] [d/l] |
That "for the most part" comment is dangerously misleading.
If you have declared script-level variables with my, then turning on warnings will give you "Cannot stay shared" warnings. Do not ignore this! It will seem to work under light testing. But it will lead to persistent weird errors in production, errors like someone occasionally getting data from someone else's page for no good reason.
What goes wrong is that the first time a given Apache process loads the page it works just fine. The second time you load it, those variables declared with my that are accessed within functions in the script are from the first request, but within the main body of the script are from the second.
If you wish to understand why, read Re (tilly) 9: Why are closures cool? and then realize that Apache::Registry works by putting a function around your entire script, eval's that, and then calls that function for each request. Which creates exactly the configuration of that node. So the my variables are accessed within your script just fine - but in functions in your script you get the first request that that Apache process saw. (And in light testing you can easily miss this.)
If you don't wish to understand why, just remember to turn warnings on, and don't ignore the message that they give. In particular the shared warnings can generally be fixed by declaring the variable in question to be global.
Incidentally the porting link you provide covers this point first because so many people get it wrong and then don't understand the weird bugs that they get. Which is why it is important that anyone telling others how to do it should do likewise, so that we don't get more confused people who only look for the code example, port their code, see that it is faster, and then wonder where the weird bugs that people are complaining about came from. (Note that common mis-advice for how to apply strict.pm is, "Just declare everything with my" - which compounds the problem.)
| [reply] |
| [reply] |
i've been reading though the online mod_perl guide. i read the third book mentioned a while ago but it's about to come off the shelf.
i'm trying to decide which is going to be better -- writing the app and running it under Apache::Registry, or writing an app that starts with mod_perl ( Apache::DBI, etc ) and stays there. i don't see the client moving the site to another server ... so i think it's safe to write a 100% mod_perl app. | [reply] |
mod_perl is pretty common in OpenSource OSs. As an example, Redhat has provided apache w/ mod_perl since rh 6.1 or 6.2.
Apache::Registry does give you that 'out' though. I actually did some code that way - so it would run both with and wihout mod_perl. In fact I did it both ways on the same box, in the same directory, using a Location directive to use apacche registry if the url was, eg, /perl/... and letting it be regular CGI if the URL was, eg, /cgi-bin/... it's not hard
--Bob Niederman, http://bob-n.com
| [reply] |