about summary refs log tree commit homepage
path: root/lib/PublicInbox/NNTP.pm
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2016-05-24 03:41:51 +0000
committerEric Wong <e@80x24.org>2016-05-24 04:12:03 +0000
commit74bbc3da398d00ba12e9294e360ad177ab2061ed (patch)
tree964f723b1072e848c4db177ab43ba5461c657e89 /lib/PublicInbox/NNTP.pm
parente330b2eec13ebda99a7e2981375dee4fe397f14a (diff)
downloadpublic-inbox-74bbc3da398d00ba12e9294e360ad177ab2061ed.tar.gz
Standardize the code we have in place to avoid creating too many
timer objects.  We do not need exact timers for things that don't
need to be run ASAP, so we can play things fast and loose to avoid
wasting power with unnecessary wakeups.

We only need two classes of timers:

* asap - run this on the next loop tick, after operating on
  @Danga::Socket::ToClose to close remaining sockets

* later - run at some point in the future.  It could be as
  soon as immediately (like "asap"), and as late as 60s into
  the future.

In the future, we support an "emergency" switch to fire "later"
timers immediately.
Diffstat (limited to 'lib/PublicInbox/NNTP.pm')
-rw-r--r--lib/PublicInbox/NNTP.pm30
1 files changed, 13 insertions, 17 deletions
diff --git a/lib/PublicInbox/NNTP.pm b/lib/PublicInbox/NNTP.pm
index ac536f71..f3de4b1c 100644
--- a/lib/PublicInbox/NNTP.pm
+++ b/lib/PublicInbox/NNTP.pm
@@ -11,6 +11,7 @@ use PublicInbox::Search;
 use PublicInbox::Msgmap;
 use PublicInbox::Git;
 use PublicInbox::MID qw(mid2path);
+require PublicInbox::EvCleanup;
 use Email::Simple;
 use POSIX qw(strftime);
 use Time::HiRes qw(clock_gettime CLOCK_MONOTONIC);
@@ -38,15 +39,15 @@ my $LIST_HEADERS = join("\r\n", @OVERVIEW,
 my %DISABLED; # = map { $_ => 1 } qw(xover list_overview_fmt newnews xhdr);
 
 my $EXPMAP; # fd -> [ idle_time, $self ]
-my $EXPTIMER;
+my $expt;
 our $EXPTIME = 180; # 3 minutes
 my $WEAKEN = {}; # string(nntpd) -> nntpd
-my $WEAKTIMER;
+my $weakt;
+my $nextt;
 
-my $next_tick;
 my $nextq = [];
 sub next_tick () {
-        $next_tick = undef;
+        $nextt = undef;
         my $q = $nextq;
         $nextq = [];
         foreach my $nntp (@$q) {
@@ -70,7 +71,7 @@ sub update_idle_time ($) {
 # reduce FD pressure by closing some "git cat-file --batch" processes
 # and unused FDs for msgmap and Xapian indices
 sub weaken_groups () {
-        $WEAKTIMER = undef;
+        $weakt = undef;
         foreach my $nntpd (values %$WEAKEN) {
                 $_->weaken_all foreach (@{$nntpd->{grouplist}});
         }
@@ -81,7 +82,6 @@ sub expire_old () {
         my $now = now();
         my $exp = $EXPTIME;
         my $old = $now - $exp;
-        my $next = $now + $exp;
         my $nr = 0;
         my %new;
         while (my ($fd, $v) = each %$EXPMAP) {
@@ -89,26 +89,22 @@ sub expire_old () {
                 if ($idle_time < $old) {
                         $nntp->close; # idempotent
                 } else {
-                        my $nexp = $idle_time + $exp;
-                        $next = $nexp if ($nexp < $next);
                         ++$nr;
                         $new{$fd} = $v;
                 }
         }
         $EXPMAP = \%new;
         if ($nr) {
-                $next -= $now;
-                $next = 0 if $next < 0;
-                $EXPTIMER = Danga::Socket->AddTimer($next, *expire_old);
+                $expt = PublicInbox::EvCleanup::later(*expire_old);
                 weaken_groups();
         } else {
-                $EXPTIMER = undef;
+                $expt = undef;
                 # noop to kick outselves out of the loop ASAP so descriptors
                 # really get closed
-                Danga::Socket->AddTimer(0, sub {});
+                PublicInbox::EvCleanup::asap(sub {});
 
                 # grace period for reaping resources
-                $WEAKTIMER ||= Danga::Socket->AddTimer(30, *weaken_groups);
+                $weakt ||= PublicInbox::EvCleanup::later(*weaken_groups);
         }
 }
 
@@ -122,7 +118,7 @@ sub new ($$$) {
         $self->watch_read(1);
         update_idle_time($self);
         $WEAKEN->{"$nntpd"} = $nntpd;
-        $EXPTIMER ||= Danga::Socket->AddTimer($EXPTIME, *expire_old);
+        $expt ||= PublicInbox::EvCleanup::later(*expire_old);
         $self;
 }
 
@@ -633,7 +629,7 @@ sub long_response ($$$$) {
                         update_idle_time($self);
 
                         push @$nextq, $self;
-                        $next_tick ||= Danga::Socket->AddTimer(0, *next_tick);
+                        $nextt ||= PublicInbox::EvCleanup::asap(*next_tick);
                 } else { # all done!
                         $self->{long_res} = undef;
                         $self->watch_read(1);
@@ -996,7 +992,7 @@ sub watch_read {
                 # in case we really did dispatch a read event and started
                 # another long response.
                 push @$nextq, $self;
-                $next_tick ||= Danga::Socket->AddTimer(0, *next_tick);
+                $nextt ||= PublicInbox::EvCleanup::asap(*next_tick);
         }
         $rv;
 }