Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

mod_perl advice required

by stew (Scribe)
on Feb 25, 2003 at 14:42 UTC ( [id://238439]=perlquestion: print w/replies, xml ) Need Help??

stew has asked for the wisdom of the Perl Monks concerning the following question:

Hello again!,

Can any one advise me of the common pitfalls associated with mod_perl?

I have a search script that ran OK as a CGI but now I'm running it under mod_perl strange things are happening. Basicaly when I do a search for the first time the results come out as expected, however when I run repeat searches the previous results appear to be appended to the first results.

FYI, in my httpd.conf I have mod_perl referenced as ..

PerlModule Apache::Registry <Location /perl> SetHandler perl-script PerlHandler Apache::Registry Options ExecCGI PerlSendHeader On allow from all </Location>
Don't know if this has anything to do with it

Cheers

Stew

Replies are listed 'Best First'.
•Re: mod_perl advice required
by merlyn (Sage) on Feb 25, 2003 at 15:01 UTC
(jeffa) Re: mod_perl advice required
by jeffa (Bishop) on Feb 25, 2003 at 14:50 UTC
    Hi stew. We really need to see your search code (i hope it's not too terribly long). The problem with Apache::Registry is that it basically shoves your program into a 'global namespace' that is shared among the Apache child processes. This means that if you have global variables in your code, you are going to have big troubles.

    I recommend ditching Apache::Registry and jumping into the real mod_perl by writing a module instead of just dropping a script in a playpen and hoping that it plays nice with the other 'children'. Grab a copy of the mod_perl Developer's Cookbook, it is invaluable.

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
      And I highly recommend following the advice given in this book to read the Eagle Book cover to cover, twice.
Re: mod_perl advice required
by DrManhattan (Chaplain) on Feb 25, 2003 at 15:01 UTC

    You might be running into variable persistance. If your variables are globally scoped, they'll hold their values between page loads.

    Another common problem is declaring a lexically scoped variable and then trying to use it in a subroutine, e.g.

    my $foo = "bar"; sub foo { # It's ok to use $foo here in a normal script, # but it may have strange results under mod_perl print $foo; }
    Here is a more detailed explanation.

    Post the relevant section of code, and we can probably help you out.

    -Matt

Re: mod_perl advice required
by tall_man (Parson) on Feb 25, 2003 at 14:59 UTC
    The book mod_perl Developer's Cookbook is a good reference to get if you do much mod_perl work. Here is what they suggest about migrating CGI scripts.

    You can quickly mode that old Perl CGI script to mod_perl by using the Apache::PerlRun module. The performance benefits are good but not outstanding.

    The difference between Apache::PerlRun and Apache::Registry is that the former scrubs the namespace between runs.

Re: mod_perl advice required
by mattr (Curate) on Feb 26, 2003 at 03:30 UTC
    Dear Stew,

    It really sounds like you have been hitting your head against some really basic and well-known mod_perl things. So the last post about RTFM is an extremely good idea. Mod_perl requires a bit of reading when you start and then some experimentation until you get used to it.

    Regarding your questions:

    1. mod_perl embeds a single persistent perl interpreter instance in apache as opposed to launching a new one each time a page is opened. So you typically use a parent program (launched once when the server is soft-restarted) and a child program (called from a browser, but also sharing the memory of the parent).
    2. This means if you use global variables they will clobber you right on the head, being shared across all calls to one or all of the apache server child processes. one of the very first programming examples (a counter) in the docs does what you are talking about. (hint: use lexicals)
    3. Likewise with database connections, if you happen to open a db connection in your child code it will stay open. probably would work if you undef'd it but you can also open a connection in the parent, there is in fact a connection pool module for this purpose. read about it.
    4. In general the really extremely good advice is to use strict. mod_perl *will* have your brain for breakfast if you do not use strict. 'nuf said.
    5. If you are porting from CGI there is also good documentation in the same place on porting from cgi.
    Good luck. Mod_perl is definitely worth it, but you have not yet invested the time and effort required to get you into it, since you would already be using strict if you had even opened the cover of the book. Just the first part of the free documentation might be enough but then you will want to read more, hopefully. I recommend if you don't like reading, to stop using mod_perl since you get out of it exactly what you put into it. Of course you can run like CGI in this environment, see the docs.
Re: mod_perl advice required
by stew (Scribe) on Feb 25, 2003 at 15:26 UTC
    Well as you can probably guess I'm a mod_perl/perl newbie, trying to feel my way along learning as I go. What you say makes perfect sense, but heres some of my search code anyway.

    #!/usr/bin/perl -W use CGI qw(param); use CGI::Carp qw(fatalsToBrowser); use DBIx::FullTextSearch; use DBIx::FullTextSearch::StopList; use DBI; use HTML::Template; use HTML::Template::Expr; my $dbh = DBI->connect('dbi:mysql:search','??????','??????') or die("C +ould not connect to database"); my $cbh = DBI->connect('dbi:mysql:cobra3','??????','??????') or die("C +ould not connect to database"); my $search = param("search_string"); my $fts = DBIx::FullTextSearch->open($dbh, '??????'); my @files = $fts->search($search); if (@files) { foreach $filename(@files){ $filename = substr($filename,0,-4); my $sth = $cbh->prepare("SELECT id, title, summary FROM resourc +e WHERE id =?"); $sth->execute($filename); while (my $ref = $sth->fetchrow_hashref()){ my $title = $ref->{title}; my $id = $ref->{id}; push @rows, { ID => $id, TITLE => $title }; } } } my $template = HTML::Template->new(filename => 'ee_search.tmpl'); $template->param(SEARCH_STRING => $search); $template->param(ROWS => \@rows); print "Content-type: text/html\n\n"; print $template->output;
    I know this is a big hint for me but I use 'strict' I get an error, I'm not sure how to assign the $filename and @rows to an explicit package name???

      strict is your friend. :) It's telling you that you need to explicitly scope $filename and @rows. Try this:

      my @rows;
      if (@files) {
          foreach my $filename(@files){
      $filename = substr($filename,0,-4); my $sth = $cbh->prepare("SELECT id, title, summary FROM resourc +e WHERE id =?"); $sth->execute($filename); while (my $ref = $sth->fetchrow_hashref()){ my $title = $ref->{title}; my $id = $ref->{id}; push @rows, { ID => $id, TITLE => $title }; } } } my $template = HTML::Template->new(filename => 'ee_search.tmpl'); $template->param(SEARCH_STRING => $search); $template->param(ROWS => \@rows);

      -Matt

        In a way, use strict is more important than warnings.
      Hi ,

      The use strict pragma is important as your program runs through mod-perl as mod-perl behaves negatively if you have variables that are global without scope and as you know use strict will surely not entertain global variables

        Not quite correct. It will not entertain undeclared global variables. (Or undeclared lexical variables, for that matter, but AFAIK a variable has to be declared to be lexically scoped anyway.)

Re: mod_perl advice required
by stew (Scribe) on Feb 25, 2003 at 16:23 UTC
    excellent it works, on more question, a PHP/MySQL application just bombed out because there wasn't enough connections, could this be down to something in this code?
      Do you mean it ran out of MySQL connections? Your code as it stands should not be using more connections than it was when running as a CGI. Are you using Apache::DBI?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://238439]
Approved by davis
Front-paged by VSarkiss
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (5)
As of 2024-04-16 20:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found