We have a setup where most code, before being promoted to full production, is deployed in BETA mode - meaning, it runs in full production environment (using production database - usually production data; and production web server). We call that stage BETA testing.
One of the main requirements is that BETA code promotion to production must be a simple "cp" command from beta to production directory - no code/filename changes.
For non-web Perl code, achieving seamless BETA test is quite doable (see details here):
- Perl programs live in a standard location under production root (
/usr/code/scripts
) with production perl modules living under the same root (/usr/code/lib/perl
) - The BETA code has 100% same code paths except under beta root (
/usr/code/beta/
) - A special module manipulates
@INC
of any script based on whether the script was called from/usr/code/scripts
or/usr/code/test/scripts
, to include beta libraries for beta scripts.
This setup works fine up till we need to beta test our web Perl code (the setup is EmbPerl and Apache/mod_perl).
The hang-up is as follows: if both a production Perl module and BETA Perl module have the same name (e.g. /usr/code/lib/perl/MyLib1.pm
and /usr/code/beta/lib/perl/MyLib1.pm
), then mod_perl will only be able to load ONE of these modules into memory - and there's no way we are aware of for a particular web page to affect which version of the module is currently loaded due to concurrency issues.
Leaving aside the obvious non-programming solution (get a bloody BETA web server) which for political/organizational reasons is not feasible, is there any way we can somehow hack around this problem in either Perl or mod_perl?
I played around with various approaches to unloading Perl modules that %INC
has listed, but the problem remains that another user might load a beta page at just the right (or rather wrong) moment and have the beta module loaded which will be used for my production page.