+if (COUNT_FROM_VARNISH_LOG) {
+ // Note: We abuse serve_url as a regex.
+ var varnishncsa = child_process.spawn(
+ 'varnishncsa', ['-F', '%{%s}t %U %q tffb=%{Varnish:time_firstbyte}x',
+ '-q', 'ReqURL ~ "^' + serve_url + '"']);
+ var rl = readline.createInterface({
+ input: varnishncsa.stdout,
+ output: varnishncsa.stdin,
+ terminal: false
+ });
+
+ var uniques = [];
+ rl.on('line', function(line) {
+ var v = line.match(/(\d+) .*\?ims=\d+&unique=(.*) tffb=(.*)/);
+ if (v) {
+ uniques[v[2]] = {
+ last_seen: (parseInt(v[1]) + parseFloat(v[3])) * 1e3,
+ grace: null,
+ };
+ log(v[1] + " " + v[2] + " " + v[3]);
+ } else {
+ log("VARNISHNCSA UNPARSEABLE LINE: " + line);
+ }
+ });
+ setInterval(function() {
+ var mtime = json.last_modified - 1000; // Compensate for subsecond issues.
+ var now = (new Date).getTime();
+ var num_viewers = 0;
+
+ for (var unique in uniques) {
+ ++num_viewers;
+ var last_seen = uniques[unique].last_seen;
+ if (now - last_seen <= 5000) {
+ // We've seen this user in the last five seconds;
+ // it's okay.
+ continue;
+ }
+ if (last_seen >= mtime) {
+ // This user has the latest version;
+ // they are probably just hanging.
+ continue;
+ }
+ if (uniques[unique].grace === null) {
+ // They have five seconds after a new JSON has been
+ // provided to get get it, or they're out.
+ // We don't simply use mtime, since we don't want to
+ // reset the grace timer just because a new JSON is
+ // published.
+ uniques[unique].grace = mtime;
+ }
+ if (now - uniques[unique].grace > 5000) {
+ log("Timing out " + unique + " (last_seen=" + last_seen + ", now=" + now +
+ ", mtime=" + mtime, ", grace=" + uniques[unique].grace + ")");
+ delete uniques[unique];
+ --num_viewers;
+ }
+ }
+
+ log(num_viewers + " entries in hash, mtime=" + mtime);
+ viewer_count_override = num_viewers;
+ }, 1000);
+}
+