Hi.

First, my knowledge of these things is more of the "practical, as mod_perl user" level, than based on the code. And I'm more than willing to be corrected by a real code specialist.
And forgive me if I am explaining things which you already know.

As I understand your request (and the first one that you sent), you want different VHost to run different versions of the same webapp (one specific version per VHost), and for efficiency reasons you would like this "version" to be pre-loaded and pre-compiled by mod_perl, on a per-VHost base.

And to do that, you want to find out the VHost name at the 
PerlPostConfigRequire stage.
If so, I believe that you may be slightly on the wrong track here.

A "VirtualHost" is not the same as an "Apache child/thread".
An Apache child/thread gets selected (or created and selected, if need be) when the main Apache server instance (which receives the requests, but does not itself run any) has already processed its full configuration (all VHost configs included), and needs a child/thread to handle a request just received. Initially, each child/thread is "VHost-agnostic", and each one has a copy of the full server configuration (all VHosts included). Any such child/thread /then/ "becomes" a specific VHost to handle the current request, as per the request's "Host:" header and the part of the global configuration which applies to that VHost. In other words, it is at the moment when the child/thread has already received a request to handle, and parsed its "Host:" header, that it decides to "change its personality" to become the VHost to which this request is addressed. (And the next request that is handled by this same child/thread, may be for another VHost altogether).

With reference to :
http://perl.apache.org/docs/2.0/user/handlers/server.html#Server_Life_Cycle
and the schema "Server Life Cycle" in it,
I would say that the selection of the "current" VHost only happens in the "Connection loop" parts (children/threads), and only on a per-request base.

In the PerlPostConfigRequire phase, there is no request yet, so there is no "selected" VHost yet. (But maybe, yes, it does get executed once per "VirtualHost" in the configuration; that, I really don't know. It may need to do that, just in case you have specified an option that allocates a separate perl interpreter per VHost).

I believe that the first stage at which mod_perl "knows" the VHost corresponding to the current request is :
http://perl.apache.org/docs/2.0/user/handlers/intro.html
link : PerlPostReadRequestHandler
Also : 
http://perl.apache.org/docs/2.0/user/handlers/intro.html#mod_perl_Handlers_Categories
Also : 
http://perl.apache.org/docs/2.0/api/Apache2/RequestUtil.html#C_get_server_name_

This would imply that you cannot, at the PerlPostConfigRequire level, make any decision as to whether to pre-load a particular module version based on the "current" VHost's name.

Note: there is also a sample module example at http://perl.apache.org/docs/2.0/user/handlers/server.html#Startup_Phases_Demonstration_Module
which looks like a good starting point for an easy way to test these things.

More references :
http://perl.apache.org/docs/2.0/user/handlers/server.html#mod_perl_Startup

All the above being said, I am wondering why it bothers you so, that a module is loaded and pre-compiled only when needed by the child/thread processing the request. This does cause a slight overhead, the first time any given child/thread needs that module. But for any subsequent request to the same child/thread, that module would already be in the mod_perl cache and pre-compiled, so there is no extra overhead anymore. And if you do not want this extra overhead at all, can you not specify all the module versions to be loaded, in the PerlPostConfigRequire directive ? Because then, as I understand it, when Apache creates an additional child/thread (from the main Apache instance), the "main" perl interpreter and its module cache would already contain these modules, and they would be duplicated along with perl, to the perl in the child/thread.

See also :
http://perl.apache.org/docs/2.0/api/Apache2/ServerRec.html#Limited_Functionality_under_Threaded_MPMs

P.S. There are definitely some deep and mysterious issues remaining with mod_perl, when it is running under a threaded MPM. We use only prefork MPM with mod_perl, for those reasons.



On 05.08.2019 21:01, Thorsten Schöning wrote:
Guten Tag Thorsten Schöning,
am Montag, 5. August 2019 um 19:18 schrieben Sie:

The problem is that I'm having trouble how to find the VHOST
currently executing that handler.

The only thing which came into my mind is using environment variables
per VHOST like in the following examples:

PerlSetEnv SOME_ID "0c8c1236-86de-4483-9d4b-999e2cfd17c1"
PerlPostConfigRequire "Some.pm"

Each VHOST gets it's own ID and that environment variable seems to be
uniquely available during execution of the configured package:

[Mon Aug 05 20:50:32.181559 2019] [:warn] [pid 17736:tid 704] [...]: 
0c8c1236-86de-4483-9d4b-999e2cfd17c1: 1
[Mon Aug 05 20:50:32.836195 2019] [:warn] [pid 17736:tid 704] [...]: 
9dc691d6-794a-4095-852e-e596cabf43d5: 1
[Mon Aug 05 20:50:34.180453 2019] [:warn] [pid 17736:tid 704] [...]: 
0c8c1236-86de-4483-9d4b-999e2cfd17c1: 2
[Mon Aug 05 20:50:34.830098 2019] [:warn] [pid 17736:tid 704] [...]: 
9dc691d6-794a-4095-852e-e596cabf43d5: 2

The logging code:

my $server = Apache2::ServerUtil->server();
    $server->warn(__PACKAGE__ . ": $ENV{'SOME_ID'}: " . 
Apache2::ServerUtil::restart_count());

With that in mind, one can get all VHOSTs and search for the ID they
define. It's important to note that `lookup` is not of much help here,
it doesn't seem to support searching for `PerlSetEnv` directly, but
one needs to implement that on hash refs returned for the VHOSTs
manually:

my $confTree  = Apache2::Directive::conftree();
my @vhosts    = $confTree->lookup('VirtualHost');

Each result is a hash ref containing keys and values like the
following:

$VAR1 = {\n          'PerlSetEnv' => 'AMS_MOD_PERL_PRE_LOADING_ID 
"9dc691d6-794a-4095-852e-e596cabf43d5"',\n[...]

The structure of the hash ref depends on the actual config, so it
might contain additional child hash refs I guess. Any better ideas
welcome...

Mit freundlichen Grüßen,

Thorsten Schöning


Reply via email to