edan has asked for the wisdom of the Perl Monks concerning the following question:

We are trying to migrate an existing CGI codebase to mod_perl (Apache::Registry) for performance reasons. The problem we are having is with name-spaces, because the product is composed of a 'global' instance, and possibly many 'local' instances. Currently it works like this:

How it Works Today

When a local instance is created, a new tree is created which is a copy of the global instance, and all of the CGIs and modules are symbolically linked to the global instance. This way, the global instance can be updated, and the local instance will get the changes, unless the local instance has modifications. A local instance is modified by breaking the symbolic link, i.e. copying the file to the local instance. This way local modifications can be made, with the tradeoff that global updates won't be seen. The CGIs use the local modules by modifying @INC to look in the local 'lib' diretory first.

Thus, all the CGIs and modules in all the instances use a module, which will be found in the local instance's include directory, but the module itself may or may not be a link to the global instance.

The example CGI would look like this:

#!perl BEGIN { unshift @INC, "$ENV{LOCAL_INSTANCE}/lib"; } use Some::Module; # ...

The Problem Using mod_perl

When we try to run this under mod_perl, the system breaks down. The first time a particular apache child gets called, it's compiled, and uses the module appropriate for the instance. But the next time it gets called, for possibly some other instance, it's still using the module that was compiled the first time. We need to the CGI to uise the module that is appropriate for the instance that it was caled for.

Solutions We Are Considering

How You Can Help

Has anyone run into this sort of problem before, and come up with a workable solution?

--
edan (formerly known as 3dan)

Replies are listed 'Best First'.
Re: Name-Space problems migrating to Apache::Registry
by Corion (Patriarch) on Mar 10, 2004 at 10:42 UTC

    I'd go with the Reverse Proxy route - it keeps all your separate domains separate and one run away mod_perl process dosen't affect the whole setup but only one server process.

    Of course, you'll have to set up some monitoring scripts that check the logs of all instances to see whether all Apache processes are still running.

    I have an experimental setup of Apache 2 as Reverse Proxy and several instances of Apache 1.3 as mod_perl servers behind it, listening to localhost:8xxx, and so far I haven't noticed any problems - but I haven't moved it into production yet.

    For experimenting and later for the production setup, you can start your several Apache instances via httpd -C /path/to/httpd.site.conf, so that you'll only need one httpd binary for all sites. That setup won't work well with suEXEC, but as you can run the local Apache 1 servers as the respective users, that should be no great problem.

Re: Name-Space problems migrating to Apache::Registry
by sheep (Chaplain) on Mar 10, 2004 at 11:32 UTC

    Hello,

    I ran into similar problem a while ago, and found the explanation
    in the Practical mod_perl book very helpful.
    Almost the same explanation plus the solutions to the problem are
    available on-line: Name collisions with Modules and libs.
    There are also pluses and minuses of the solutions described there.
    I am not going to rewrite this document here, as it is well informative
    and I am strongly against retyping any source information.

    For my particular problem I used the "quick but ineffective hackish solution",
    with deleting $INC{"mymodule.pm"} and unshifting @INC within the BEGIN block,
    when it was necessary, and then normally with "use mymodule;".

    Regards,

    -sheep
Re: Name-Space problems migrating to Apache::Registry
by perrin (Chancellor) on Mar 10, 2004 at 15:38 UTC
    There are at multiple ways to handle this. One is to use the approach that sheep was talking about: modify @INC to what you want, delete the modules in question from %INC, and then require them. This will reload them.

    Alternatively, you can use Apache::PerlVINC which does it all for you so you don't need to change your code.

    Neither of these will be as fast as not reloading anything, so you should probably think about a better way to do your customization in the long term, but they will get things working for now.

      Thanks - didn't know about Apache::PerlVINC. We are trying to avoid reloading every time, because then you lose a lot of the benefit that mod_perl is giving you. Trying to use different namespaces at least would only load once for each instance, rather than every time...

      --
      edan (formerly known as 3dan)

Re: Name-Space problems migrating to Apache::Registry
by bageler (Hermit) on Mar 10, 2004 at 13:12 UTC
    you could change use to eval "require 'Some::Module'" to bring it in at runtime. use brings it all in at compile time.

      True, but it doesn't solve the problem. perl will still only 'bring it in' once, since it has the same name. I need to have the CGI use a different module (which has the same name currently) for each instance. I'm beginning to think the Reverse Proxy solution is the best, unless someone else comes up a with a brilliant plan...

      --
      edan (formerly known as 3dan)