|
| Author |
Message |
Addict Not Yet a God

Joined: 21 Jan 2004 Posts: 473
   
|
Posted: Mon Apr 25, 2005 9:58 pm Post subject: |
|
|
True, but who cares, just change it, if you use it.  |
|
| Back to top |
|
 |
Dazzy Agent

Joined: 09 Jan 2004 Posts: 1731
 
|
Posted: Tue Apr 26, 2005 7:07 am Post subject: |
|
|
| Code: | | print "<b>There have been ".$counter->{Hits}." hit\(s\) to this page!</b>\n\n"; |
 |
|
| Back to top |
|
 |
mattaustin Sentinel

Joined: 19 Jul 2004 Posts: 556 Location: Los Angeles, CA
  votes: 1
|
Posted: Tue Apr 26, 2005 7:12 am Post subject: |
|
|
lol good one daz  _________________ [ matt ] |
|
| Back to top |
|
 |
eric256 The Keymaker

Joined: 03 May 2006 Posts: 2292 Location: Colorado
     
|
Posted: Tue Apr 26, 2005 2:22 pm Post subject: |
|
|
When building counter scripts you should learn about locking. The problem is that web servers may run two of your script at the same time..
It is easier to see with an example.
| Code: | | <br />use Data::Dumper;<br />my $counter = do("./hits.dat"); #<- line a<br />sub Save<br />{<br /> open SAVE, "> ./hits.dat"; #<-- line b<br /> print SAVE Dumper($counter);<br /> close(SAVE);<br /> my $counter = do("./hits.dat");<br />}<br /> $counter->{Hits}++; Save;<br /> print "Content-type: text/html\n\n";<br /> print "<b>There has been ".$counter->{Hits}." to this page!</b>\n\n";<br /> |
So lets say that the first instance of the script starts. It gets to A and all is good. Now it opens the file to save but before it gets a chance to save the new counter data and second instance is started. The file is now empty because the first script opened it with > which blanks out the file. The second isntance gets to line A and find the file empty. The first instance gets control agian and saves the correct value for it and finishs. Now the second instance gets back control and saves its value, but its value is 0 because it opened an empty file. Now it saves that 0 over the correct number saved by A.
I know it sounds lke a long shot but if you page gets called a few times in a rush by one or more people then the odds of it dieing like this become very high. Locking would allow you to only have one instance reading and writing to the file at the same time. Look up flock on perldoc.org for more info. _________________ Eric256
Proud previous owner and current admin of Bot-depot.com |
|
| Back to top |
|
 |
Dazzy Agent

Joined: 09 Jan 2004 Posts: 1731
 
|
Posted: Tue Apr 26, 2005 2:35 pm Post subject: |
|
|
it would have to be Very quick though i guess? I mean, the amount of hashs you record in a second is quite a few....less that half a second i guess.....But the risk is still there... |
|
| Back to top |
|
 |
Cer Upgraded Agent

Joined: 03 Feb 2004 Posts: 3776 Location: Michigan
  votes: 4
|
Posted: Tue Apr 26, 2005 6:46 pm Post subject: |
|
|
What I do for file locking is use Fcntl ':flock';
| Code: | | use Fcntl ':flock';<br /><br />use Data::Dumper;<br />my $counter = do("./hits.dat"); #<- line a<br />sub Save<br />{<br /> open SAVE, "> ./hits.dat"; #<-- line b<br /><br /> # Gain exclusive lock (only this script has access)<br /> flock (SAVE, LOCK_EX);<br /><br /> print SAVE Dumper($counter);<br /><br /> # Unlock the file.<br /> flock (SAVE, LOCK_UN);<br /><br /> close(SAVE);<br /> my $counter = do("./hits.dat");<br />}<br /> $counter->{Hits}++; Save;<br /> print "Content-type: text/html\n\n";<br /> print "<b>There has been ".$counter->{Hits}." to this page!</b>\n\n"; |
I found that from some online tutorial but haven't properly tested it (or haven't purposely tested it). So if somebody sees something wrong there they can just reply about it. Probably File::Lock is an easier way to do it too.  _________________ Current Site (2008) http://www.cuvou.com/ |
|
| Back to top |
|
 |
eric256 The Keymaker

Joined: 03 May 2006 Posts: 2292 Location: Colorado
     
|
Posted: Wed Apr 27, 2005 5:14 am Post subject: |
|
|
Dazzy it is more likely to occur than you think. Plus if it occurs once and you arn't prepared you loose everything. Wanna take that risk? 
Cer - The problem with that is that you are only locking it for the writing portion, which doesn't fix anything. Instead the normal way is to use a semaphore (or a flag if you prefer). At the start of your script you open a file (you can open the script itself if you want) and lock that file handle. Then do whatever you need to do. When the script ends the lock is released. This way your script will never have two instances running at once. If you have alot happening in your script you can follow the same idea but only lock the file for the portion where you read, add, and write. You lock a seperate file because you need to open the counter file 2 and you want to make sure that the value hasn't changed since you last read the file (meaning a nother script squeezed in the middle).
It is a kinda confusing concept I know but trust that it can happen as i have had it happen to me before. Of course I was saving the whole structure of a portol and not just a counter so I was quite upset when i figured out what happened. ;( _________________ Eric256
Proud previous owner and current admin of Bot-depot.com |
|
| Back to top |
|
 |
draget Not Yet a God

Joined: 29 Dec 2004 Posts: 367 Location: Australia
   
|
Posted: Wed Apr 27, 2005 10:42 am Post subject: |
|
|
CGI/CGI::Carp ->  |
|
| Back to top |
|
 |
Cer Upgraded Agent

Joined: 03 Feb 2004 Posts: 3776 Location: Michigan
  votes: 4
|
Posted: Wed Apr 27, 2005 11:32 am Post subject: |
|
|
QUOTE(draget @ Apr 27 2005, 06:42 AM) CGI/CGI::Carp ->  [right][snapback]48050[/snapback][/right] |
I don't see how CGI::Carp has anything to do with it.
Eric: So locking the entire script would be like this?
| Code: | | #!/usr/bin/perl -w<br />use Fcntl ':flock';<br />open (SELF, "file.cgi");<br />flock (SELF, LOCK_EX);<br /><br /># do other file operations<br />open (FILE, ">file.dat");<br />print FILE "test";<br />close (FILE);<br /><br />__END__ |
Or is that still off? _________________ Current Site (2008) http://www.cuvou.com/ |