mod_perl, "use lib", and stuff ...

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View

Hi perlers,

I'm developing a web based thing with mod_perl and apache. One of the
things that has bugged me has been running 2 or 3 versions of the site
(say dev and test), all using a common library "MyLib". The whole thing
is under version control, with the layout looking like this (excuse
abysmal attempt at line drawing):

----MyLib (contains "", ""
---- site ---- cgi --- app.cgi

Now app.cgi contains the following lines:

use lib "../..";
use MyLib::X;

The site dir symlinks to /var/www/mysite, and at run time the intention
(which seems to work) is that a given release sees it's own MyLib, the
one in it's own projectDir.

At least that's what I thought, until I started getting odd effects
that indicated that maybe *some* of the processes were seeing a
different "". Then I read the docs and gotthis:

Even though @INC typically includes dot ("."), the current directory,
this really isn't as useful as you'd think. For one thing, the dot
entry comes at the end, not the start, so that modules installed in the
current directory don't suddenly override system versions. You could
say use lib "." if that's what you really want. More annoyingly, it's
the current directory of the Perl process, not the directory that the
script was installed into, which makes it completely unreliable. If you
create a program plus some modules for that program to use, it will
work while you're developing, but it won't work when you aren't running
in the directory the files live in.

What the hell does THAT mean in teh context of mod_perl? What is the cd
of the mod_pelr process? How is this thing working at all?

And more to the point, what is a better way get the process to see the
right modules, that I can set up from an installation script? i.e I
want to export a tree from teh repository, and then run a script to set
up the symlinks correctly - for more than version of the site.

Thanks to anyone who can help unravel this knot. I can'ty be the first
to tread this weary path ...


Re: mod_perl, "use lib", and stuff ... wrote:
Quoted text here. Click to load it

Your problem is fundamental. Under mod_perl the Perl interpreter can
persist from one request to the next.  That's like the whole point.  If
a module has already been loaded during the processing of request 1 you
don't have to pay the price of loading it again  during the handling of
request 2.  The flip side of this is that if a module has already been
loaded during the processing of request 1 then request 2 comes along
and sets a different @INC you'll still be using whatever version was
loaded first.

In a development environment you can get over this by limiting each
interpreter to handling a single request - but of course you loose most
of the beniefit of mod_perl.

Alternatively have a separate Apache instance per version.

In mod_perl2 there's apparently a way of defining multiple pools of
Perl servers (and I believe you can set @INC differently in each) and
then assigning those pools to different virtual directories.  That way
you could get away with a single Apache.  I suspect that if there were
a significant number of versions about this could prove even less
efficient than the one-request-per-interpreter solution.

There may  also be solutions using special Apache module like
Apache::StatINC but IMNSHO any solution based on unloading Perl modules
is likely to cause as many problems as it solves. (Note: I'm not saying
Apache::StatINC would be any help at all, I'm saying a similar approach
to that used in Apache::StatINC might be applicable).

Quoted text here. Click to load it

You probably should never rely on relative paths in @INC when running

Actually, you probably should never rely on relative paths in @INC when
running perl. That is what the above stanza was trying to convey.

Re: mod_perl, "use lib", and stuff ... wrote:

Quoted text here. Click to load it

    This is (probably) the simplest thing to do.

    You can have one set of Apache executables and one set of web-site
files, but multiple Apache configs (although most of that can be common too
- just Include the majority of your config into a little file which has a:

    use lib qw( /the/dir/I/want/for/this/one );

section in it), each setting different @INC in the configs. Run them on
different ports to select which version you want.

Quoted text here. Click to load it

    parent and clone options to a Perl* var IIRC.

    Also, I have a vague feeling that '.' isn't on @INC in mod_perl2 (may
be wrong - enable perl-status to check...)

              Just because I've written it doesn't mean that
                   either you or I have to believe it.

Re: mod_perl, "use lib", and stuff ...

Thanks. Good advice. Understanding the problem is all, as usual.

I looked at various other fixes, like FindBin::Real and Perl_VINC
modules, but none of them seemed to be quite what I wanted. In the end
running two apache-perl instances was it - took a bit of figuring out,
but looks a nice clean solution.

Site Timeline