W. Tyler Gee wrote:
On Tue, Aug 19, 2008 at 5:35 PM, Chris Faust <[EMAIL PROTECTED]> wrote:
Hi,



This might be a little off topic, I hope it's OK to post. I'm not positive
if mod_perl matters or not because it's a little confusing to me.



I've taken over some pretty old code that I'm updating and making mp2
content handlers out of. The main script is a standard cgi script
"start.cgi" there is nothing special in the apache conf for it.



        <Directory /xxx/>

        SetHandler perl-script

        PerlFixupHandler My::Fixup

        PerlResponseHandler ModPerl::PerlRun

        PerlOptions +ParseHeaders

        DirectoryIndex start.cgi

        Options +ExecCGI +Indexes

        allow from all

        </Directory>



start.cgi calls a custom module (use CustomModule;) which exports a bunch of
subs, for example foobar and all over the place in the subs that are
exported from CustomModule I see code like





sub foobar {

            my $key = @_;



            if ($cache{$key}) {

                        return $cache{$key};

            } else {

                        my $do_some_query = xxxx;

                        $cache{$key} = $do_some_query_results

                        return $cache{$key};

            }

}



My question is isn't the "else" in foobar always going to be true anyplace
where start.cgi is calling "&foobar('somekey')"??????

I don't understand how %cache could already be populate from a previous
browser request or something? I'm I just missing something stupid?

%cache is defined outside the scope of the sub so it will persist for
the lifetime of the apache server.  The very first time
foobar('somekey') is called it will do the query lookup, the next time
it will return from cache.

I believe the above is almost, but not totally true. It should probably be "for the lifetime of this particular apache child". Each apache child process has it's own copy of the above code, and it's own copy of the above "global" (*) %cache hash. Thus whether the first or second part of the if will run, depends of the previous history of the particular apache child which handles the current request. If this particular child has already previously accessed the same hash key, it will server it from (it's own) cache, and otherwise it will execute the query to create the key (in it's own cache). Apache children are created, and die, as directed by the main Apache process configuration, and HTTP requests are served more or less at random, by whichever child is available when the request comes in. Is is thus quite possible for instance that the first 10 requests for a particular hash key would each be handled by a different apache child, and would each result in a query; then the 11th request would be handled by a child that has already accessed this same key before, and thus served from cache; the 13th request would be handled by a brand-new apache child just created, thus would re-do the query, etc..

I this would be useful, I believe that it would be possible to avoid this, by "priming" the mod_perl module during the initial start of Apache, before it forks into children. Then each new child (being a copy of the main apache) would start it's life with a number of keys already in its cache. Of course this would work only if the contents of the keys of the hash are never modified while apache is running. And it probably involves some delicate mod_perl programming to do the priming process.

(*) like the previous contributor, I guess that the %cache hash is somehow global, because it is not declared within the sub that you show. Whether it really is though, may depend on other code that we don't see here. But anyway, "global" would mean only "global to this apache child", not to the whole apache server.

And something that I don't know at all, is how this all works out with a threaded apache, such as under Windows e.g.

André

Reply via email to