Different modules, same names, random results

2003-02-04 Thread Pinunki
Hello everyone,

I am currently running a web server using Perl CGI for
all my web sites and have been attracted to mod_perl
for the performance advantages - particularly not
having to start a new perl interpreter for each
request. I have tried using Apache::Register and
Apache::PerlRun but am having problems due to the fact
that each web site refers to their own copy of my
module called Site.pm (to contain functions, global
variables etc). The problem is that the my scripts get
confused and use variables from the other site's
modules randomly.

The following example is using Apache::PerlRun (as
it's supposed to be more forgiving that
Apache::Register). I am using Apache 1.3.26 and
mod_perl 1.26 on Debian Woody.


.htaccess
-

PerlModule  Apache::PerlRun

files *.pl
  SetHandler  perl-script
  PerlHandler Apache::PerlRun
  Options +ExecCGI
/files


site1.pl


#!/usr/bin/perl

use strict;
use CGI;

use lib lib1;
use Site;

my $q = new CGI;

print $q-header();

print EOF;
  Site 1br
  VAR: $VARbr
EOF


lib1/Site.pm


#!/usr/bin/perl -w

package Site;
require Exporter;

use strict;

our $VAR = Site one;

our @ISA = qw(Exporter);
our @EXPORT = qw($VAR);

1;


site2.pl


#!/usr/bin/perl

use strict;
use CGI;

use lib lib2;
use Site;

my $q = new CGI;

print $q-header();

print EOF;
  Site 2br
  VAR: $VARbr
EOF


lib2/Site.pm


#!/usr/bin/perl -w

package Site;
require Exporter;

use strict;

our $VAR = Site two;

our @ISA = qw(Exporter);
our @EXPORT = qw($VAR);

1;


I then call site1.pl and site2.pl multiple times and
get output like this:

Site 1
VAR: Site two

Site 1
VAR: Site one

Site 1
VAR: Site two

Site 2
VAR: Site two

Site 2
VAR: Site two

Site 2
VAR: Site one


I can fix this problem by adding the line PerlSetVar
PerlRunOnce On to my .htaccess file, but my
performance tests show that this is actually slower
than regular CGI!!

Is there anything I can do to make this work properly
without renaming all my Site.pm modules (and all
scripts that call them) to have unique names?


Thanks,
Pinunki


__
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com



Re: Different modules, same names, random results

2003-02-04 Thread David Dick
this is probably evil, and apologies to those who have seen suspiciously 
familiar code before, but is this possible?

package MyPrefix::Apache::Registry;
use strict;

BEGIN {
  use Apache::Registry();
}

sub handler {
  delete $INC{'Site.pm'};
# mess with @INC
  require Site;
  return (Apache::Registry::handler(@_));
}

END { }

1;

that would allow you to keep perl resident, keep the cgi-scrip resident 
and simply reload a small? configuation perl module each time.
(i think?) :)

Uru
-Dave

Pinunki wrote:

Hello everyone,

I am currently running a web server using Perl CGI for
all my web sites and have been attracted to mod_perl
for the performance advantages - particularly not
having to start a new perl interpreter for each
request. I have tried using Apache::Register and
Apache::PerlRun but am having problems due to the fact
that each web site refers to their own copy of my
module called Site.pm (to contain functions, global
variables etc). The problem is that the my scripts get
confused and use variables from the other site's
modules randomly.

The following example is using Apache::PerlRun (as
it's supposed to be more forgiving that
Apache::Register). I am using Apache 1.3.26 and
mod_perl 1.26 on Debian Woody.


.htaccess
-

PerlModule  Apache::PerlRun

files *.pl
 SetHandler  perl-script
 PerlHandler Apache::PerlRun
 Options +ExecCGI
/files


site1.pl


#!/usr/bin/perl

use strict;
use CGI;

use lib lib1;
use Site;

my $q = new CGI;

print $q-header();

print EOF;
 Site 1br
 VAR: $VARbr
EOF


lib1/Site.pm


#!/usr/bin/perl -w

package Site;
require Exporter;

use strict;

our $VAR = Site one;

our @ISA = qw(Exporter);
our @EXPORT = qw($VAR);

1;


site2.pl


#!/usr/bin/perl

use strict;
use CGI;

use lib lib2;
use Site;

my $q = new CGI;

print $q-header();

print EOF;
 Site 2br
 VAR: $VARbr
EOF


lib2/Site.pm


#!/usr/bin/perl -w

package Site;
require Exporter;

use strict;

our $VAR = Site two;

our @ISA = qw(Exporter);
our @EXPORT = qw($VAR);

1;


I then call site1.pl and site2.pl multiple times and
get output like this:

Site 1
VAR: Site two

Site 1
VAR: Site one

Site 1
VAR: Site two

Site 2
VAR: Site two

Site 2
VAR: Site two

Site 2
VAR: Site one


I can fix this problem by adding the line PerlSetVar
PerlRunOnce On to my .htaccess file, but my
performance tests show that this is actually slower
than regular CGI!!

Is there anything I can do to make this work properly
without renaming all my Site.pm modules (and all
scripts that call them) to have unique names?


Thanks,
Pinunki


__
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com

 





Re: Different modules, same names, random results

2003-02-04 Thread Stas Bekman
David Dick wrote:

this is probably evil, and apologies to those who have seen suspiciously 
familiar code before, but is this possible?

package MyPrefix::Apache::Registry;
use strict;

BEGIN {
  use Apache::Registry();
}

sub handler {
  delete $INC{'Site.pm'};
# mess with @INC
  require Site;
  return (Apache::Registry::handler(@_));
}

a simpler way is to do:

  do Site.pm;

though you forgot to call the import, when removing use, so you do:

  do Site.pm;
  Site-import(whatever);

and if you use:

   use warnings;

you probably want to add:

  no warnings 'redefine';


END { }

1;

that would allow you to keep perl resident, keep the cgi-scrip resident 
and simply reload a small? configuation perl module each time.
(i think?) :)

indeed. This is discussed here:
http://perl.apache.org/docs/1.0/guide/porting.html#Name_collisions_with_Modules_and_libs

__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com




Re: Different modules, same names, random results

2003-02-04 Thread Stas Bekman
Pinunki wrote:
[...]
 I have tried using Apache::Register and

Apache::PerlRun but am having problems due to the fact
that each web site refers to their own copy of my
module called Site.pm (to contain functions, global
variables etc). The problem is that the my scripts get
confused and use variables from the other site's
modules randomly.

[...]

If your module which has an indentical name but different contents and it 
never calls functions and accesses variables by prefixing the module name 
(e.g. Site::foo and $Site::bar), i.e. everything is exported, you could hack 
Apache::Registry to compile the different files into different package names 
and do the importing for you. Here is the proof of concept (untested!) code. 
All it does, is reading the file (Site.pm in your case), prepending the string

  'package foo_bar_tar_lib1_Site_pm;'

to the contents of the file, compiling the module via eval and then calling 
import() to import all the stuff as it did before. Notice that you do have to 
change your scripts to call the trickery my_use().

(Alternatively you could try to play with aliasing of the namespaces, instead 
of mangling the file contents, but this could introduce problems...)

my_script.pl:
-
my @imports();
Apache::Registry::my_use('Site.pm', @imports);

Site.pm
---
# no package declaration!
# the rest is as usual Exporter, vars, subs
# blah, blah
1;

Registry.pm
---

package Apache::Registry;

# the normal Registry stuff ...

# then the extra stuff:

use File::Spec::Functions;

sub my_use {
my($module, @import) = @_;

my $file = catfile Apache-request-filename, $module;

my $namespace = make_namespace($file);

compile($namespace, $file) or die failed to compile: $@;

$namespace-import(@import);

}

sub make_namespace {
my ($path) = @_;

$path =~ s/([^A-Za-z0-9_])/sprintf(_%2x, unpack(C, $1))/eg;

# make sure that the sub-package doesn't start with a digit
$path =~ s/^(\d)/_$1/;

return $path;
}

sub compile {
my ($namespace, $file) = @_;

open my $fh, $file;
local $/;
my $data = $fh;
close $fh;

{ eval package $namespace;\n $data; }
return $@ ? 0 : 1;
}

1;


__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com