Mailing List Archive

RESOLVED Catalyst modperl2 Problem
Hi all,

After lots of tracing around the code I have resolved the Apache2/ModPerl2
problem.

Basically what happens is that modperl2 does not call handler as a method (with
$self as the first argument) by default.

In order to fix this I added the following to Catalyst::Engine::Apache

sub handler_mp1($$) {
my $class = shift;
$class->SUPER::handler(@_);
}

eval {
sub handler_mp2 : method {
my $class = shift;
$class->SUPER::handler(@_);
}
};

if($@) {
*handler = \&handler_mp1;
} else {
*handler = MP2 ? \&handler_mp2 : \&handler_mp1;
}

The above should behave correctly in either modperl1 or modperl2, but it is
untested under modperl1 as I do not have a modperl1 server handy.

The modperl2 handler uses a new language feature as of perl 5.6.0 so I eval it
and silently go to the modperl1 handler if I get an error.

If you want to use modperl2 with perl < 5.6.0 then may god have mercy on your
soul. Actually you can just put sub handler { MyApp->SUPER::handler(@_); } in
each application module where MyApp is the fully qualified package name, but
that's just ugly.

Cheers,

Blain
RESOLVED Catalyst modperl2 Problem [ In reply to ]
Am 01.04.2005 um 23:16 schrieb bsadler@helix-it.com:
> sub handler_mp1($$) {
> my $class = shift;
> $class->SUPER::handler(@_);
> }
>
> eval {
> sub handler_mp2 : method {
> my $class = shift;
> $class->SUPER::handler(@_);
> }
> };
>
> if($@) {
> *handler = \&handler_mp1;
> } else {
> *handler = MP2 ? \&handler_mp2 : \&handler_mp1;
> }

That looks just wrong!
Can you come up with a minimal testcase? maybe a small handler without
catalyst?

--
sebastian
RESOLVED Catalyst modperl2 Problem [ In reply to ]
On Friday 01 April 2005 04:30 pm, Sebastian Riedel wrote:
> Am 01.04.2005 um 23:16 schrieb bsadler@helix-it.com:
> > sub handler_mp1($$) {
> > my $class = shift;
> > $class->SUPER::handler(@_);
> > }
> >
> > eval {
> > sub handler_mp2 : method {
> > my $class = shift;
> > $class->SUPER::handler(@_);
> > }
> > };
> >
> > if($@) {
> > *handler = \&handler_mp1;
> > } else {
> > *handler = MP2 ? \&handler_mp2 : \&handler_mp1;
> > }
>
> That looks just wrong!
> Can you come up with a minimal testcase? maybe a small handler without
> catalyst?
>
> --
> sebastian

Perhaps it is ugly, but it works. This is pretty much straight from the lions
mouth at
http://perl.apache.org/docs/2.0/user/porting/porting.html#Porting_a_Module_to_Run_under_both_mod_perl_2_0_and_mod_perl_1_0
so I have a certain amount of faith that no better method for running under
both MP1 and MP2 has been found.

Of course you can clean up my crap code and use the slightly more elegant:

sub handler_mp1 ($$) { &generic_handler };
eval {
sub handler_mp2 : method { &generic_handler };
};
# line noise... I know
*handler = MP2 && !$@ ? \&handler_mp2 : \&handler_mp1;

sub generic_handler {
my $class = shift;
$class->SUPER::handler(@_);
}

Again, the only reason for the eval is not to break Catalyst for those using
perl < 5.6.0 which can't handle the ': method' bit.

As far as a test case for MP2 goes:

package MyTest;
use strict;
use warnings;

use mod_perl;
use constant MP2 => $mod_perl::VERSION < 1.99 ? 0 : 1;

BEGIN {
warn "running $mod_perl::VERSION!\n";
if (MP2) {
require Apache::RequestRec;
require Apache::RequestIO;
require Apache::Const;
Apache::Const->import(-compile => 'OK');
}
else {
require Apache;
require Apache::Constants;
Apache::Constants->import('OK');
}
}
sub handler($$) {
my ($class, $r) = @_;
warn("class is a: " .$class); #prints Apache::RequestRec under MP2
warn("r is a : " . $r); # prints undef under MP2
}
1;

package MyTest2;
use strict;
use warnings;

use mod_perl;
use constant MP2 => $mod_perl::VERSION < 1.99 ? 0 : 1;

BEGIN {
warn "running $mod_perl::VERSION!\n";
if (MP2) {
require Apache::RequestRec;
require Apache::RequestIO;
require Apache::Const;
Apache::Const->import(-compile => 'OK');
}
else {
require Apache;
require Apache::Constants;
Apache::Constants->import('OK');
}
}
sub handler : method {
my($class, $r) = @_;
warn("class is a: " .$class); #prints MyTest2 under MP2
warn("r is a : " . $r); # prints Apache::RequestRec under MP2
}
1;

Cheers,

Blain