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

Most serene masters,
I have, with your help, made this search engine which is working wonderfully. I come to you to ask if the file called top.html below needs to be flocked during the execution of the sub. I believe it does not, but I wanted to be sure. Since I am not writing to the HTML file when I append the search results, will multiple simultaneous executions be a problem?
TIA
jg

PS Yes I know I am not making the most of CGI here.
sub return_html { my %include = %{$_[0]}; open(FH,"/home/coolsite/www/top.html") || die "couldn't open file $ +!\n"; my @html=<FH>; close(FH); print "Content-type: text/html\n\n"; print @html; my %titles = %{$_[1]}; print "\n <center>\n <h1>Search Results</h1>\n </center>\n"; print "RESULTS- In No Particular Order:<p><hr size=7 width=75%><p>\ +n"; print "<ul>\n"; foreach my $key (keys %include) { if ($include{$key} eq 'yes') { print "<li class=bullets><span class=bullets><a href=\"$baseu +rl$key\">$titles{$key}</a></span></li>\n"; } } print "</ul>\n"; print "\n"; print "</ul><br><hr size=7 width=75%><P>\n"; print "<ul>\n<li class=bullets><span class=bullets><a href=\"$searc +h_url\">Back to Search Page</a></span></li>\n"; print "<li class=bullets><span class=bullets><a href=\"$title_url\" +>$title</a></span></li>\n"; print "</ul>\n"; print "<hr size=7 width=75%>\n"; print "<center>\n"; print "This search powered by<br>\n"; print "<a href=http://www.mysite.com><img src=../nolalogo.jpg width +=318 height=74 border=0 alt=\"Got Funk?\"></a>\n"; print "</center>\n"; print "</body>\n</html>\n";
_____________________________________________________
Ain't no time to hate! Barely time to wait! ~RH

Replies are listed 'Best First'.
Re: Do I need to give a flock?
by Corion (Patriarch) on Oct 08, 2001 at 00:45 UTC

    File locking (and resource locking in general) is only needed when resource contention is likely to happen and the resulting problems outweigh the problems you have by implementing the locking mechanism.

    In your case, you only use top.html for reading in the code, and it seems to me like top.html is part of some search-result template. If this is the case, then top.html does not change often, and is written to only when somebody copies over a new version of it. The results of reading a half-written top.html would be that somebody gets a broken page, which is fixed by the moment they reload it. If all of that were the case, locking would be overhead that has no practical value, as people will see broken results because of bad connections more often anyway.

    If you had a second CGI which updates top.html much more often (say every minute), your chance of producing broken HTML would increase. You could then still try to avoid locking with some fancy file renaming tricks. But the risk of getting a lock conflict because one script tries to write and the other tries to read from the half-written file is still there and you're heading into lock-land.

    The case where you will absolutely need locking is, when you have two (or more) scripts (or two instances of the same script) that try to write to the same file at the same time. In this case you will always need locking.


    perl -MHTTP::Daemon -MHTTP::Response -MLWP::Simple -e ' ; # The $d = new HTTP::Daemon and fork and getprint $d->url and exit;#spider ($c = $d->accept())->get_request(); $c->send_response( new #in the HTTP::Response(200,$_,$_,qq(Just another Perl hacker\n))); ' # web
Re (tilly) 1: Do I need to give a flock?
by tilly (Archbishop) on Oct 08, 2001 at 01:20 UTC
    First an answer to your question.

    No, you probably don't need a flock. On Unix I can guarantee that you don't if your strategy for rewriting the file is to write it to a different name and then rename the new one on top of the old. Otherwise the worst that can happen is a low likelyhood of a page from time to time which is somewhat truncated. (If you do flock, make it a shared lock.)

    However you do have many other things about your coding style that could be worked on. For instance a function with return in the name suggests that you are returning stuff. You are not, so the name should better reflect what you are doing. Also it is good to break out argument processing so that it is obvious from a glance what arguments your subroutine takes. And it would be good to do more separation of content and presentation. Aggressively inlined HTML makes both program logic and layout harder to see and manipulate...

Re: Do I need to give a flock?
by tachyon (Chancellor) on Oct 08, 2001 at 02:00 UTC

    You will save yourself a lot of work by using a Herepage. You can interpolate variables into them but do not have to \ your ". This save lots of calls to print and makes your code so much easier to read. Here is an example:

    sub unindent; # declare unindent proto at top of code so we can use it + as a bareword sub return_html { my %include = %{$_[0]}; open(FH,"/home/coolsite/www/top.html") || die "couldn't open file +$!"; my @html=<FH>; close(FH); my %titles = %{$_[1]}; my $results; foreach my $key (keys %include) { if ($include{$key} eq 'yes') { $results .= "<li class=bullets><span class=bullets><a href=\ +"$baseurl$key\">$titles{$key}</a></span></li>"; } } print unindent <<" HTML"; # print all the stuff until we find H +TML on a line by itself Content-type: text/html @html <center> <h1>Search Results</h1> </center> RESULTS- In No Particular Order:<p><hr size=7 width=75%><p> <ul> $results </ul> </ul> <br> <hr size=7 width=75%> <P> <ul> <li class=bullets><span class=bullets><a href="$search_url">Back + to Search Page</a></span></li> <li class=bullets><span class=bullets><a href="$title_url">$titl +e</a></span></li> </ul> <hr size=7 width=75%> <center> This search powered by<br> <a href=http://www.mysite.com><img src=../nolalogo.jpg width=318 + height=74 border=0 alt=\"Got Funk?\"></a> </center> </body> </html> HTML # herepage ends with token above } # this sub strips all leading whitespace sub unindent { s/^[ \t]+//gm for @_; @_; }

    This uses a trick to let you indent your HTML with the sub. The herepage token we use has 4 leading spaces then the letters HTML ie "    HTML" so indents with the HTML. To remove the indentation for efficiency we declare an unindent() sub proto at the top of our code so we can use it as a bareword (effectively like an inbuilt function). This sub strips all the leading whitespace and will reduce the download by 20-50%+ plus depending on how you format your HTML.

    PS you have an extra/unmatched </ul> in there which is a little easier to see now too.

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print