antonkomarev / github-profile-views-counter

It counts how many times your GitHub profile has been viewed. Free cloud micro-service.
https://komarev.com/sources/github-profile-views-counter
MIT License
4.06k stars 369 forks source link

Write console command to re-calculate counter aggregate value #71

Open antonkomarev opened 1 year ago

antonkomarev commented 1 year ago

After fix (by @Brikaa) of counter reset because of the race condition (#66) we need to create console command which will re-calculate correct counter values. It should count lines in storage/{username}-views file and store them to storage/{username}-views-count.

Something like:

cat storage/{username}-views | wc -l | tr -d ' ' > storage/{username}-views-count

But we should iterate thru all the usernames in the storage directory. There are many counter files, so ls -la is hanging for a long time.

One more thing to ensure: we need to make -1 from wc -l, because of the empty line at the end of file.

antonkomarev commented 1 year ago

It looks like this command can compute correct value:

awk 'END {print NR-1}' storage/{username}-views > storage/{username}-views-count
Brikaa commented 1 year ago

I believe wc -l does not count the new line at the end of the file

$ echo -e "hello\nthere" > test.txt && wc -l test.txt
2 test.txt
antonkomarev commented 1 year ago

Try

echo -e "hello\nthere\n" > test.txt && wc -l test.txt
Brikaa commented 1 year ago

That puts two new lines at the end of the file.

antonkomarev commented 1 year ago

That's exactly how views are stored. We have a blank line on the end of the file.

Brikaa commented 1 year ago

Yes, but your example puts two blank lines at the end of the file. image

Brikaa commented 1 year ago

Does the following script using Perl's readdir() for listing the directory content hang? It shouldn't try to read the entire directory content at once.

my $dir = "/app/storage";
opendir(my $dh, $dir) || die "Can't open $dir: $!";
while (my $f = readdir $dh) {
  print "$dir/$f\n";
}
closedir $dh;

Save it as filename.pl and run in the container it using:

perl filename.pl

If it doesn't we can build upon that.

If it hangs, we can consider fixing the user on each HTTP request. We can have a flag that determines if a certain username is fixed, and on each request we check if the flag exists. If it doesn't, we fix the user and create the flag.