X-Git-Url: https://git.sesse.net/?p=remoteglot;a=blobdiff_plain;f=www%2Fanalysis.pl;h=f650bedd082d376dd674ee9a7211b0cf4a9322bf;hp=b7e99b6639d951401654b58f282acaf8d4d292f3;hb=5426efdc76c6a78aceb84ab8b3de262ccb3cfdf3;hpb=799c4b5cbf8c8aac97c3dbb8c36a1f06aa5e1220 diff --git a/www/analysis.pl b/www/analysis.pl index b7e99b6..f650bed 100755 --- a/www/analysis.pl +++ b/www/analysis.pl @@ -1,13 +1,13 @@ #! /usr/bin/perl use CGI; -use POSIX; -use Date::Manip; use Linux::Inotify2; use AnyEvent; +use IPC::ShareLite; +use Storable; use strict; use warnings; -my $json_filename = "/srv/analysis.sesse.net/www/analysis.json"; +our $json_filename = "/srv/analysis.sesse.net/www/analysis.json"; my $cv = AnyEvent->condvar; my $updated = 0; @@ -26,11 +26,14 @@ my $wait = AnyEvent->timer ( cb => sub { $cv->send; }, ); +my $unique = $cgi->param('unique'); +our $num_viewers = count_viewers($unique); + +# Yes, this is reinventing If-Modified-Since, but browsers are so incredibly +# unpredictable on this, so blargh. my $ims = 0; -if (exists($ENV{'HTTP_IF_MODIFIED_SINCE'})) { - my $date = Date::Manip::Date->new; - $date->parse($ENV{'HTTP_IF_MODIFIED_SINCE'}); - $ims = $date->printf("%s"); +if (defined($cgi->param('ims')) && $cgi->param('ims') ne '') { + $ims = $cgi->param('ims'); } my $time = (stat($json_filename))[9]; @@ -40,20 +43,43 @@ if ($time > $ims) { exit; } -# If not, wait, then send. Apache will deal with the 304-ing. -if (defined($cgi->param('first')) && $cgi->param('first') != 1) { - $cv->recv; -} +# If not, wait, then send. +$cv->recv; output(); -sub output { - my $time = (stat($json_filename))[9]; - my $lm_str = POSIX::strftime("%a, %d %b %Y %H:%M:%S %z", localtime($time)); +sub count_viewers { + my $unique = shift; + my $time = time; + my $share = IPC::ShareLite->new( + -key => 'RGLT', + -create => 'yes', + -destroy => 'no', + -size => 1048576, + ) or die "IPC::ShareLite: $!"; + $share->lock(IPC::ShareLite::LOCK_EX); + my $viewers = {}; + eval { + $viewers = Storable::thaw($share->fetch()); + }; + $viewers->{$unique} = time; - print CGI->header(-type=>'text/json', - -last_modified=>$lm_str, - -access_control_allow_origin=>'http://analysis.sesse.net', - -expires=>'now'); + # Go through and remove old viewers, and count them at the same time. + my $num_viewers = 0; + while (my ($key, $value) = each %$viewers) { + if ($time - $value > 60) { + delete $viewers->{$key}; + } else { + ++$num_viewers; + } + } + + $share->store(Storable::freeze($viewers)); + $share->unlock(); + + return $num_viewers; +} + +sub output { open my $fh, "<", $json_filename or die "$json_filename: $!"; my $data; @@ -61,5 +87,14 @@ sub output { local $/ = undef; $data = <$fh>; } + my $time = (stat($fh))[9]; + close $fh; + + print CGI->header(-type=>'text/json', + -x_remoteglot_last_modified=>$time, + -x_remoteglot_num_viewers=>$num_viewers, + -access_control_allow_origin=>'http://analysis.sesse.net', + -access_control_expose_headers=>'X-Remoteglot-Last-Modified, X-Remoteglot-Num-Viewers', + -expires=>'now'); print $data; }