[Home]PersistentCGI

UseModWiki | RecentChanges | Preferences

Running UseMod with Apache & mod_perl

UseModWiki 1.0 can run under Apache either with mod_cgi and mod_perl. If you've followed the instructions at UseModWiki/Install, you are now running your wiki with mod_cgi. Your site will work fine, but it could be made much faster with mod_perl.

Install and test mod_perl before making changes to your environment.

Add the following to your website's configuration:

PerlModule Apache::Registry
<Location /path/to/wiki.pl>
    SetHandler perl-script
    PerlHandler Apache::Registry
    Options +ExecCGI
    PerlSendHeader On
    Allow from all
</Location>

You are likely to experience a noticable speedup. Caveat: unlike mod_cgi, mod_perl doesn't work with Apache's "suexec" mechanism.

Older UseMod Versions

The rest of this page discusses version 0.92 and older. It is no longer relevant for version 1.0


A list of ideas and changes to make UseModWiki work better with "persistent" CGI environments such as mod_perl, SpeedyCGI, and FastCGI. I have done only minimal testing of UseModWiki with mod_perl, but I've always intended for it to work. Eventually I plan to do more extensive testing in the mod_perl environment, probably when UseModWiki gets closer to the 1.0 release. --CliffordAdams


Has anyone noticed the link between WikiBugs/LongPageGetsTruncated and running under mod_perl? Just curious. I can't seem to run Persistent due to the bug. --LukeStark

I've just made some changes to Mike James UseModWiki 0.92 package to clean it up a bit under mod_perl. I wanted to be able to install Wiki::UseModWiki once on my site and then still be able to invoke it from within apache's httpd.conf. In particular, I didn't want $DataDir fixed in stone. So I added

  $DataDir = $ENV{WikiDataDir} if $UseConfig && defined $ENV{WikiDataDir}

to the beginning of &DoWikiRequest, and then invoke the wiki from within http.conf via

 PerlModule Wiki::UseModWiki
 <Location /url/path/to/wiki>
   PerlSetEnv WikiDataDir '/home/your/path/to/wikidb'
   SetHandler perl-script
   PerlHandler Wiki::UseModWiki::DoWikiRequest
 </Location>

I also made some changes to allow a code formatting utility called "code2html" to be invoked from within the wiki, but you probably don't care about those.

You can find details and my modifications at [MSIE SiteLog] if you're interested.

 --JimMahoney

An alternative is to make the data dir an optional argument of DoWikiRequest.


Here's what I think is a bug fix for running uder mod_perl.

While running 0.92 under mod_perl, we've been still seeing the "persistent ID" problem described below - users who don't have a cookie set end up with the ID of the last person to edit a page.

But now I believe that clearing %UserData fixes the problem.

old code:

 sub InitCookie {
 # ... other stuff
 undef $q->{'.cookies'}; # Clear cache if it exists (for SpeedyCGI)
 %UserCookie = $q->cookie($CookieName);
 # ... other stuff
 }

new code:

 sub InitCookie {
 # ... other stuff
 undef $q->{'.cookies'}; # Clear cache if it exists (for SpeedyCGI)

 %UserData = ();   # <=== Added this line

 %UserCookie = $q->cookie($CookieName);
 # ... other stuff
 }

--JimMahoney


Installed Mike's repack for mod_perl, works fine outside, but spits this message a million times in the error_log, every time:

[Tue Jul 31 23:03:44 2001] wiki.pl: Use of uninitialized value in concatenation (.) at /usr/lib/perl5/site_perl/5.6.0/Wiki?/UseModWiki?.pm line 788.

Cliff, Mike: how can I extinguish this log pollutant? -- [Alexy Khrabrov]

The easy way is to turn off warnings by removing the "-w" from the first line of the executable, "#!/usr/bin/perl -w" . --JimMahoney


Umm, do you need to call wiki.pl differently when you're running under Apache::Registry or Apache::PerlRun??

What I mean is, wiki.pl runs fine in CGI mode ($RunCGI=1) when called as <my.server.name/cgi-bin/wiki.pl>, but when $RunCGI=0 and Apache's httpd.conf is set for Apache::Registry or Apache::PerlRun?, the result is "Internal Server Error" with this in the Apache error log:

 [Fri May 25 09:09:36 2001] [error] [client x.x.x.x] Premature end of script headers: /usr/pkg/libexec/cgi-bin/wiki.pl

(I think I'm overlooking something obvious.) --MikeJames

This message could simply be because the script isn't being run at all. If you set $RunCGI=0, then you need to explicitly call the &UseModWiki::DoWikiRequest() subroutine for each request. I'm a little rusty on how to do this under Apache, but I think there is a setting for the Perl subroutine to call for each request. Just point that setting at &UseModWiki::DoWikiRequest() and it should work. --CliffordAdams (or double your money back :-)

Thanks--I have it working now! I've made a draft HOWTO at MikeJames. If anyone's interested, give it a try. (And update the HOWTO, including moving it somewhere else if appropriate.)


Well, I've got the "Premature end of script headers" error as well. And it's quite strange. I got it when I tried to save the page [1] after copying the complete contents into the edit field. But I was able to generate the page without any error when copied in three pieces one after the other (first was up to "(Version 1.0)", second up to "Die Gründungsmitglieder Winkler, Andel, Otten, Gaide, Herzig, Jeker.", i.e. almost the complete contents(!), and third the last three lines).

So whatever the reason, I managed to do what I wanted to, but I'd like to understand what is going on here!

Any hints greatly appreciated. -- DavidAndel


You should be able to speed up the script by changing the code in two places:



$BrowseCode = ""; # Comment next line to always compile (slower)


$BrowseCode = <<'#END_OF_BROWSE_CODE';


...and further down:



$OtherCode = ""; # Comment next line to always compile (slower)


$OtherCode = <<'#END_OF_OTHER_CODE';


For maximum speed, you should comment out the lines containing END_OF_....._CODE, so that they look like:



$BrowseCode = ""; # Comment next line to always compile (slower)


#$BrowseCode = <<'#END_OF_BROWSE_CODE';


...and further down:



$OtherCode = ""; # Comment next line to always compile (slower)


#$OtherCode = <<'#END_OF_OTHER_CODE';


This change will make the script compile only once the first time it is executed. (For ordinary CGI execution, this change would be slower because it would do extra compiling every time a page is loaded. With persistent scripts, you want to do as much compilation the first time as possible.) --CliffordAdams



The patches below are obsoleted with the 0.92 release.


One small change that might be necessary for persistent CGI is to clear a cookie cache used internally by CGI.pm. The reported problem was that after a user with a user-ID cookie visited, the next user who did not have a cookie would have the same user-ID (username and preferences) as the previous cookie-using user.

I recommended the following change, but I didn't hear back from the user whether it fixed the problem. That would have been me, DanMuller. It seemed to fix the problem. (The cause of the behavior seems to be that CGI.pm uses a cache internally.) The following change is part of the development code, and will be in 0.92.

We're still seeing this problem in the 0.92 release running under mod_perl. I haven't done much testing and don't yet understand exactly what causes the error, but a number of messages have been attributed in RecentChanges to the wrong person. See http://bob.marlboro.edu/~msie/2002/wiki/wiki?SiteLog

old code:



sub InitCookie {


  %SetCookie = ();


  $TimeZoneOffset = 0;


  %UserCookie = $q->cookie($CookieName);


new code:



sub InitCookie {


  %SetCookie = ();


  $TimeZoneOffset = 0;


  undef $q->{'.cookies'};  # Clear cache if it exists (for SpeedyCGI)


  %UserCookie = $q->cookie($CookieName);


(The only change is the additional commented line.) --CliffordAdams


I have converted wiki.pl for compatibility with Apache mod_perl and Apache::Registry, which gives tremendous speed improvements. [--BobShowalter]

Very interesting, is it available for public consumption? --KlausSeistrup

(Yes, see patches below --BobShowalter)

Wonderful, thanks! Now, please tell an apache newbie (I'm using Zope right now) how I combine wiki.pl with mod_perl. Cheers. --kas

See http://perl.apache.org/ for a big list of links on mod_perl. People who want to use mod_perl or persistent CGI scripts should also look at the SpeedyCGI page for a significant speedup.

I like the changes in the two patches below. ...a little later... I've made a few changes in the development version:

Any comments or other ideas? --CliffordAdams


Patches

Here are a couple of patches to wiki.pl version 0.91. The patches are context diff listings and can be fed directly to the patch utility (see http://www.gnu.org/software/patch/patch.html). You can apply the patches in any combination.

Patch 1: Apache::Registry (mod_perl) compatibility. This patch localizes all global variables used by the script for Apache::Registry compatibility. $^T was especially important, since changes to it non-locally will wreak havoc with Apache::Registry's automatic recompile mechanism. Note: this patch should be completely harmless even if you are not using Apache::Registry.



*** wiki.pl Mon Feb 12 17:50:25 2001


--- wiki.pl.1 Fri Mar 30 11:14:10 2001


***************


*** 26,31 ****


--- 26,32 ----


  #    59 Temple Place, Suite 330


  #    Boston, MA 02111-1307 USA


  


+ local ($|, $/, $^T);


  $| = 1;    # Do not buffer output


  undef $/;  # Read complete files


  use strict;


***************


*** 43,48 ****


--- 44,62 ----


    $ShowEdits $ThinLine $LinkPattern $InterLinkPattern $InterSitePattern


    $UrlProtocols $UrlPattern $ImageExtensions $RFCPattern $ISBNPattern


    $FS $FS1 $FS2 $FS3 $CookieName $SiteBase);


+ local (@RcDays, @HtmlPairs, @HtmlSingle,


+   $TempDir, $LockDir, $DataDir, $HtmlDir, $UserDir, $KeepDir, $PageDir,


+   $InterFile, $RcFile, $RcOldFile, $IndexFile, $FullUrl, $SiteName, $HomePage,


+   $LogoUrl, $RcDefault, $IndentLimit, $RecentTop, $EditAllowed, $UseDiff,


+   $UseSubpage, $UseCache, $RawHtml, $SimpleLinks, $NonEnglish, $LogoLeft,


+   $KeepDays, $HtmlTags, $HtmlLinks, $UseDiffLog, $KeepMajor, $KeepAuthor,


+   $UseEmailNotify, $SendMail, $NotifyDefault, $EmailFrom,


+   $ScriptTZ, $BracketText, $UseAmPm, $UseConfig, $UseIndex,


+   $RedirType, $AdminPass, $EditPass, $UseHeadings, $NetworkFile, $BracketWiki,


+   $FreeLinks, $WikiLinks, $AdminDelete, $FreeLinkPattern, $RCName,


+   $ShowEdits, $ThinLine, $LinkPattern, $InterLinkPattern, $InterSitePattern,


+   $UrlProtocols, $UrlPattern, $ImageExtensions, $RFCPattern, $ISBNPattern,


+   $FS, $FS1, $FS2, $FS3, $CookieName, $SiteBase);


  # Other global variables:


  use vars qw(%Page %Section %Text %InterSite %SaveUrl %SaveNumUrl


    %KeptRevisions %UserCookie %SetCookie %UserData %IndexHash


***************


*** 49,54 ****


--- 63,73 ----


    $InterSiteInit $SaveUrlIndex $SaveNumUrlIndex $MainPage


    $OpenPageName @KeptList @IndexList $IndexInit


    $q $UserID $TimeZoneOffset $ScriptName $BrowseCode $OtherCode);


+ local (%Page, %Section, %Text, %InterSite, %SaveUrl, %SaveNumUrl,


+   %KeptRevisions, %UserCookie, %SetCookie, %UserData, %IndexHash,


+   $InterSiteInit, $SaveUrlIndex, $SaveNumUrlIndex, $MainPage,


+   $OpenPageName, @KeptList, @IndexList, $IndexInit,


+   $q, $UserID, $TimeZoneOffset, $ScriptName, $BrowseCode, $OtherCode);


  


  # == Configuration =====================================================


  $DataDir     = "/tmp/mywikidb"; # Main wiki directory


Patch 2: Use FastGlob? module. This patch uses the FastGlob? module (available from http://www.cpan.org/ at [2]) to do file globbing. This avoids the fork to csh and eliminates a bunch of errors in my Apache error_log due to glob failures. The result is a significant speed improvement on my system.

Apparently, beginning with v5.6.0, the glob operator is implemented using the standard File::Glob extension. --DanielNeri



*** wiki.pl Mon Feb 12 17:50:25 2001


--- wiki.pl.2 Fri Mar 30 11:19:20 2001


***************


*** 266,271 ****


--- 266,272 ----


  #$BrowseCode = <<'#END_OF_BROWSE_CODE';


  use CGI;


  use CGI::Carp qw(fatalsToBrowser);


+ use FastGlob ();


  


  sub InitRequest {


    my @ScriptPath = split('/', "$ENV{SCRIPT_NAME}");


***************


*** 2109,2123 ****


  sub GenerateAllPagesList {


    my (@pages, @dirs, $id, $dir);


  


!   @dirs = qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z other);


!   foreach $dir (@dirs) {


!     while (<$PageDir/$dir/*.db $PageDir/$dir/*/*.db>) {


        s|^$PageDir/||;


        m|^[^/]+/(\S*).db|;


        $id = $1;


        push(@pages, $id);


      }


-   }


    return sort(@pages);


  }


  


--- 2110,2121 ----


  sub GenerateAllPagesList {


    my (@pages, @dirs, $id, $dir);


  


!    for (FastGlob::glob("$PageDir/*/*.db"), FastGlob::glob("$PageDir/*/*/*.db")) {


        s|^$PageDir/||;


        m|^[^/]+/(\S*).db|;


        $id = $1;


        push(@pages, $id);


      }


    return sort(@pages);


  }


  



UseModWiki | RecentChanges | Preferences
Edit text of this page | View other revisions | Search MetaWiki
Last edited October 8, 2006 5:08 pm by MarkusLude (diff)
Search: