Fix an issue where varnishcount would undercount on low traffic.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Wed, 17 Jun 2015 21:43:58 +0000 (23:43 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Wed, 17 Jun 2015 21:43:58 +0000 (23:43 +0200)
Basically AnyEvent and line buffering is tricky; we could end up
reading only the first line even though there were many more ready,
causing us to see the lines from varnishncsa lines way too late
and thus oscillating between ~30 and ~0 viewers.

It's crazy that you need to fiddle with push_read() in the read
callback instead of just being able to set line => directly in the
constructor, but this is seemingly the right idiom.

varnishcount.pl

index 1aa0e6f..7411b05 100755 (executable)
@@ -12,13 +12,17 @@ open my $fh, "-|", "varnishncsa -F '%{%s}t %U %q tffb=%{Varnish:time_firstbyte}x
        or die "varnishncsa: $!";
 my %uniques = ();
 
-my $ev = AnyEvent->io(
+my $ev = AnyEvent::Handle->new(
        fh => $fh,
-        poll => 'r',
-       cb => sub {
-               chomp (my $input = <$fh>);
-               handle_line($input);
-       }
+       on_read => sub {
+               my ($hdl) = @_;
+               $hdl->push_read(
+                       line => sub {
+                               my ($hdl, $line, $eof) = @_;
+                               handle_line($line);
+                       }
+               );
+       },
 );
 my $ev2 = AnyEvent->timer(
        interval => 1.0,