Results 1 to 14 of 14
Thread: Counter problems
-
05-27-2005, 08:48 PM #1Newbie
- Join Date
- Jan 2005
- Posts
- 21
Counter problems
Hi,
I currently have a perl counter. What happens is that when a html page is loaded the javascript calls a perl file to update the counter and read the value.
The perl script works this way:
It open the counter file in read mode, reads the value updates it by 1 and then closes it. It then opens the file in Write mode and writes the new count and closes.
If the file does not exist it creates a new oen and sets the counter to 0.
Problem:
The problem is that if you try to refresh this script quickly, somewhere along the way the read code locks the file and thus the second read gets a error and it assumes that the files does nto exist and the file is opened in Write mode and the counter is reset.
It perl script was written by someone else.
What is a good counter solution that will avoid this problem. Any ASP/Perl/JS solution will do.
-
05-27-2005, 10:23 PM #2Web Hosting Master
- Join Date
- Jan 2003
- Posts
- 1,715
Re: Counter problems
Originally posted by ruthless
Problem:
The problem is that if you try to refresh this script quickly, somewhere along the way the read code locks the file and thus the second read gets a error and it assumes that the files does nto exist and the file is opened in Write mode and the counter is reset.
You probably open the write with something like this:
open(FILE, '>filename.txt');
The problem is, in the time between the open and the print, the file is blank. If a read request fires during that window (which, given enough chances, it eventually will), it will read a blank and increment it to 1. The problem is compounded because you can't hold a lock between two open operations.
To handle a write like this, you should open the file in read/write mode ('+<filename.txt') and seek() back to 0 after the read. That will at least keep the data intact, so you don't reset, and it will also allow you to use flock to serialize the runs.Game Servers are the next hot market!
Slim margins, heavy support, fickle customers, and moronic suppliers!
Start your own today!
-
05-30-2005, 10:36 PM #3Junior Guru Wannabe
- Join Date
- Jan 2004
- Posts
- 78
Code:flock FILEHANDLE,2;
-
05-31-2005, 01:28 PM #4Newbie
- Join Date
- Jan 2005
- Posts
- 21
Thanks for the replies. hiryuu what you said makes a lot of sense. I really do not know perl and we use it only for counters. This is the code that opens the file reads the counter and then updates it.
Below is the code used for the counter
$file = "filename.txt";
if(! -e $file)
{
$count = 0;
}
else
{
open(CNT, "$file") || die "count not read $file";
$count = <CNT>;
chomp($count);
close(CNT);
}
if(!$show)
{
$count++;
open(CNT, ">$file") || die "could not write to $file";
print CNT $count;
close(CNT);
}
How can this be modified to avoid the problem. Any help will be appreciated.
-
05-31-2005, 01:45 PM #5Newbie
- Join Date
- Jan 2005
- Posts
- 21
I read a few file commands online and modified the write as shown below. Is this right? Also it seems to miss certain counts
if(!$show) {
$count++;
open(CNT, "+>$file") || die "could not write to $file";
flock (CNT, 2);
seek(CNT, $curpos, 0);
print CNT $count;
close(CNT);
}
-
05-31-2005, 03:45 PM #6Web Hosting Master
- Join Date
- Jan 2003
- Posts
- 1,715
It will miss counts, since concurrent requests can read the same number during the read stage.
open CNT, '+<filename.txt';
flock(CNT, 2);
$count = <CNT>;
$count++;
seek(CNT, 0, 0);
print CNT $count;
close(CNT);
This will not create the file for you, but it's otherwise one clean operation, locked the whole way through.Game Servers are the next hot market!
Slim margins, heavy support, fickle customers, and moronic suppliers!
Start your own today!
-
05-31-2005, 09:16 PM #7Newbie
- Join Date
- Jan 2005
- Posts
- 21
thanks hiryuu.
Is there a way to lock the file so that the next time the file is read it is checked to see whether there is a lock on it. Only if there is no lock on it can it been read. There will be a timeout period during which the program waits to see if the lock has been given up and if it has then it goes ahead and reads the count else it does something else.
-
05-31-2005, 09:52 PM #8Web Hosting Master
- Join Date
- Mar 2004
- Location
- USA
- Posts
- 4,345
Do you have database with your plan?
Peace,Testing 1.. Testing 1..2.. Testing 1..2..3...
-
05-31-2005, 11:04 PM #9Web Hosting Master
- Join Date
- Jan 2003
- Posts
- 1,715
Originally posted by ruthless
Is there a way to lock the file so that the next time the file is read it is checked to see whether there is a lock on it. Only if there is no lock on it can it been read.
As azizny mentions, you may want to use a database server, which transparently handles a lot of this concurrent access mess.Game Servers are the next hot market!
Slim margins, heavy support, fickle customers, and moronic suppliers!
Start your own today!
-
06-01-2005, 04:22 PM #10Web Hosting Master
- Join Date
- Mar 2004
- Location
- USA
- Posts
- 4,345
or actually maybe its just his server, I have used this counter for my sites and never done me any problems.. (even if you attack it with a billion hit!)..
Peace,Testing 1.. Testing 1..2.. Testing 1..2..3...
-
06-01-2005, 04:33 PM #11Web Hosting Master
- Join Date
- Jan 2003
- Posts
- 1,715
You're probably on a Windows system. Windows uses mandatory locking, which would prevent this issue, but comes with its own hefty can of worms.
Game Servers are the next hot market!
Slim margins, heavy support, fickle customers, and moronic suppliers!
Start your own today!
-
06-02-2005, 12:29 PM #12Newbie
- Join Date
- Jan 2005
- Posts
- 21
Thanks for the replies...
azizny... yes we have a DB with our connection. I didn't want to use the DB for counters. I will take a look at your perl script.
hiryuu... my hosting plan is windows
-
06-21-2005, 12:44 PM #13Newbie
- Join Date
- Jan 2005
- Posts
- 21
Originally posted by hiryuu
It will miss counts, since concurrent requests can read the same number during the read stage.
open CNT, '+<filename.txt';
flock(CNT, 2);
$count = <CNT>;
$count++;
seek(CNT, 0, 0);
print CNT $count;
close(CNT);
This will not create the file for you, but it's otherwise one clean operation, locked the whole way through.
open CNT, '+<$file';
flock(CNT, 2);
$count = <CNT>;
$count++;
seek(CNT, 0, 0);
print CNT $count;
close(CNT);
-
06-21-2005, 03:34 PM #14Web Hosting Master
- Join Date
- Jan 2003
- Posts
- 1,715
My mistake:
open CNT, "+<$file";
The file name wasn't a variable in the code I grabbed, so I used single quotes.Game Servers are the next hot market!
Slim margins, heavy support, fickle customers, and moronic suppliers!
Start your own today!