in reply to (jeffa) Re: thinking about mod_perl
in thread thinking about mod_perl

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.

Replies are listed 'Best First'.
Re: Re: (jeffa) Re: thinking about mod_perl
by tilly (Archbishop) on Jul 19, 2003 at 17:35 UTC
    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.)

      yes, i remember the "Cannot stay shared" messages mentioned in the mod_perl guide.

      i'm really not thinking too hard about Apache::Registry ... more about a 100% mod_perl app ... i don't have any of the perl4 code mentioned in the original reply. i'm starting at the ground level with some templates provided by the graphic designer i've teamed with for this one.