« Streaming Compressed Data with Apache Webserver | Main | Debugging Perl in Apache »

July 28, 2006

The Pain of Upgrading to Apache 2 for Perl (mod_perl) Folks

I've spent the past few days working toward upgrading our webservers from Apache 1.3.x to Apache 2 (2.0.58 at the moment). As I mentioned earlier, I've done an Apache upgrade before (and have a long history with Apache and mod_perl), but never in instances where mod_perl was used to bolt Perl onto Apache (maybe infuse is a better term). I've read various conversion documents, and even attended a tutorial or two on making the switch but haven't seen much in the way of upgrading when working with mod_perl.

The bottom line is that after spending two days working toward getting our Perl code to play nicely with Apache 2 I've gotten most of the page loads working but we've decided that it's not worth any more attention (too many outstanding issues and uncertainties). Bummer, I'd like to tame this beast at some point. I was upgrading so we could use mod_deflate for streaming compressed data, but we can do that with Apache 1.3 and Apache::Dynagzip so are going to do that for now (the benefit of mod_deflate is not worth the effort and risk of Apache 2). This mod_perl compression FAQ is excellent for an overview of the choices.

So what makes moving from Apache 1.3 to 2 with mod_perl a difficult transition?

Complexity of Application

I need to note that the instances where upgrading to Apache 2 seemed unsurmountable have been very large applications, with hundreds of Perl modules and hundreds of thousands of lines of code. These aren't small perl scripts running in Apache, these are major applications that are tied closely to the various Apache request and response stages. Makes a big difference.

New Modules

If you use any of the mod_perl-installed Apache modules you have to replace them with Apache2, ModPerl or APR modules. Unfortunately it's not as easy as grepping through the code and replacing the class name. In many cases there's a new object or method to get what you're looking for. In some instances the arguments and return value from a method has changed which may require reworking some of your code.

For example, $r = Apache->request() is replaced with $r = Apache2::RequestUtil::request(). $r->args used to be able to return an array but now will return a string only. This one isn't an issue for us, but if you were processing $r->args as an array you'd have to rework your code to be happy getting a string. You get the idea.

Moving things over is definitely doable, just a matter of taking the time. Just don't be tricked into thinking that you can easily swap out your Apache 1 and seamlessly move up to Apache 2 with your Perl code not noticing a thing. It will notice in mostly obvious ways (and perhaps in subtle ways too).

Preloading Perl

I never got to the bottom of this, but we have a series of .pl files that get loaded into Apache when it starts. We use the example provided on page 637 of the Apache modules book, which is updated for Apache 2 in the documentation. The obvious was to convert Apache::RegistryLoader to ModPerl::RegistryLoader and replace the Apache::server_root_relative with it's new counterpart.

Once I had everything in our code changed to work with Apache 2, and had changed our preload.pl script to follow the docs, I started Apache. The modules wouldn't load though, it would attempt to run them but fail on each one. I traced things down to the run method in ModPerl::RegistryCooker and now suspect the failure had something to do with the loader not being able to change directories, something that Apache/mod_perl 1 could handle.

Alas I didn't get to figure it out because the bottom line of getting compression out the door for a customer didn't warrant all the uncertainty of this move. Hope to come back to it when there are other compelling reasons to upgrade.

The Unknown

I got a chance to peruse our application a bit running on Apache 2 and there were noticeable issues to deal with. The most obvious was JavaScript being printed to the screen where it wasn't before (we use CGI for most of our HTML generation). I also noticed pieces of data printed as object names (ARRAY...).

So even though I got close my guess is that we'd need a good long period of testing to give us time to address the unknown issues that would come up.

Documentation

To the credit of the Apache-Perl folks, there's good documentation on the mapping between the old Apache stuff to Apache2 or ModPerl. Less impressive are the several places in the documentation that read something like this note in the ModPerl::Registry doc:

XXX: STOPPED here. Below is the old Apache::Registry document which I haven't worked through yet.

Which means reading or using anything below that line is probably going to lead to confusion and frustration.

Moving On

So I'm off onto other things now, but definitely a lot wiser for having really attempted and gotten close to completing a first pass at the upgrade. Not only did this give me a chance to see Apache 2 configured to do Perl it gave me a chance to dig down into the source of some of the Apache2 and ModPerl classes and see what's under the hood.

Posted by mike at July 28, 2006 12:21 PM

Hard Drive Recovery Group offers hard disk data recovery services for RAID, laptops and servers. Complete clean room and hard drive repair service.

Trackback Pings

TrackBack URL for this entry:
http://mike.kruckenberg.com/mt/mt-tb.cgi/912

Comments

"I also noticed pieces of data printed as object names (ARRAY...)."

This sounds like the output of the Data::Dumper module which stringifies Perl variables for printing to logfiles or stdout for debugging. An advantage being that you can eval them back into Perl.

I find them useful for printing out the contents of a complex hash, just feed the reference to the Dumper function.

Hope you get the Apache2 probs sorted out Mike,
Cheers,
Imran Chaudhry

BTW, can we have a go at this application you're building?

Posted by: Imran Chaudhry at August 1, 2006 9:35 AM

Imran. Not sure what you mean by 'have a go' . . . the application is commercial and provided as a service for a monthly fee:

http://www.openair.com

We have a team of in-house developers and systems folks. We're not pressed to get to Apache 2, just something I was asked to look at.

Posted by: Mike at August 1, 2006 12:03 PM

You can run apache 2.0+ with the mod_perl 1 API - rhel4 still ships this way, as do the derived distros (centos for example).

We took the shift to the mod_perl 2 API as a driver to migrate to using handlers rather than registry thingies, but our code was only mimimally tied to apache before so it was fairly simple.

Posted by: adam at January 3, 2007 8:46 AM

Post a comment




Remember Me?