From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00, URIBL_BLOCKED shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 29EA21F46C for ; Thu, 12 Dec 2019 21:16:50 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 2/3] ds: move NNTP-only expiration code into DS Date: Thu, 12 Dec 2019 21:16:48 +0000 Message-Id: <20191212211649.7824-3-e@80x24.org> In-Reply-To: <20191212211649.7824-1-e@80x24.org> References: <20191212211649.7824-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: We'll be supporting idle timeout for the HTTP code in the future to deal directly with Internet-exposed clients w/o Varnish or nginx. --- lib/PublicInbox/DS.pm | 41 +++++++++++++++++++++++++++++++++-- lib/PublicInbox/NNTP.pm | 48 +++++------------------------------------ 2 files changed, 44 insertions(+), 45 deletions(-) diff --git a/lib/PublicInbox/DS.pm b/lib/PublicInbox/DS.pm index 7eb0aada..856884bb 100644 --- a/lib/PublicInbox/DS.pm +++ b/lib/PublicInbox/DS.pm @@ -42,7 +42,9 @@ require File::Spec; my $nextq; # queue for next_tick my $WaitPids; # list of [ pid, callback, callback_arg ] my $later_queue; # callbacks -my ($later_timer, $reap_timer); +my $EXPMAP; # fd -> [ idle_time, $self ] +our $EXPTIME = 180; # 3 minutes +my ($later_timer, $reap_timer, $exp_timer); our ( %DescriptorMap, # fd (num) -> PublicInbox::DS object $Epoll, # Global epoll fd (or DSKQXS ref) @@ -73,7 +75,8 @@ sub Reset { $nextq = []; $WaitPids = []; $later_queue = []; - $reap_timer = $later_timer = undef; + $EXPMAP = {}; + $reap_timer = $later_timer = $exp_timer = undef; @ToClose = (); $LoopTimeout = -1; # no timeout by default @Timers = (); @@ -657,6 +660,40 @@ sub later ($) { $later_timer //= AddTimer(undef, 60, \&_run_later); } +sub expire_old () { + my $now = now(); + my $exp = $EXPTIME; + my $old = $now - $exp; + my %new; + while (my ($fd, $v) = each %$EXPMAP) { + my ($idle_time, $ds_obj) = @$v; + if ($idle_time < $old) { + if (!$ds_obj->shutdn) { + $new{$fd} = $v; + } + } else { + $new{$fd} = $v; + } + } + $EXPMAP = \%new; + $exp_timer = scalar(keys %new) ? later(\&expire_old) : undef; +} + +sub update_idle_time { + my ($self) = @_; + my $sock = $self->{sock} or return; + $EXPMAP->{fileno($sock)} = [ now(), $self ]; + $exp_timer //= later(\&expire_old); +} + +sub not_idle_long { + my ($self, $now) = @_; + my $sock = $self->{sock} or return; + my $ary = $EXPMAP->{fileno($sock)} or return; + my $exp_at = $ary->[0] + $EXPTIME; + $exp_at > $now; +} + package PublicInbox::DS::Timer; # [$abs_float_firetime, $coderef]; sub cancel { diff --git a/lib/PublicInbox/NNTP.pm b/lib/PublicInbox/NNTP.pm index c9487114..6cd2b84c 100644 --- a/lib/PublicInbox/NNTP.pm +++ b/lib/PublicInbox/NNTP.pm @@ -43,35 +43,6 @@ HDR\r OVER\r my $have_deflate; -my $EXPMAP; # fd -> [ idle_time, $self ] -my $expt; -our $EXPTIME = 180; # 3 minutes - -sub update_idle_time ($) { - my ($self) = @_; - my $sock = $self->{sock} or return; - $EXPMAP->{fileno($sock)} = [ now(), $self ]; -} - -sub expire_old () { - my $now = now(); - my $exp = $EXPTIME; - my $old = $now - $exp; - my %new; - while (my ($fd, $v) = each %$EXPMAP) { - my ($idle_time, $nntp) = @$v; - if ($idle_time < $old) { - if (!$nntp->shutdn) { - $new{$fd} = $v; - } - } else { - $new{$fd} = $v; - } - } - $EXPMAP = \%new; - $expt = scalar(keys %new) ? PublicInbox::DS::later(*expire_old) - : undef; -} sub greet ($) { $_[0]->write($_[0]->{nntpd}->{greet}) }; @@ -92,8 +63,7 @@ sub new ($$$) { } else { greet($self); } - update_idle_time($self); - $expt ||= PublicInbox::DS::later(*expire_old); + $self->update_idle_time; $self; } @@ -650,7 +620,7 @@ sub long_response ($$) { out($self, " deferred[$fd] aborted - %0.6f", $diff); $self->close; } elsif ($more) { # $self->{wbuf}: - update_idle_time($self); + $self->update_idle_time; # COMPRESS users all share the same DEFLATE context. # Flush it here to ensure clients don't see @@ -983,7 +953,7 @@ sub event_step { return unless $self->flush_write && $self->{sock}; - update_idle_time($self); + $self->update_idle_time; # only read more requests if we've drained the write buffer, # otherwise we can be buffering infinitely w/o backpressure @@ -1008,25 +978,17 @@ sub event_step { my $len = bytes::length($$rbuf); return $self->close if ($len >= LINE_MAX); $self->rbuf_idle($rbuf); - update_idle_time($self); + $self->update_idle_time; # maybe there's more pipelined data, or we'll have # to register it for socket-readiness notifications $self->requeue unless $self->{wbuf}; } -sub not_idle_long ($$) { - my ($self, $now) = @_; - my $sock = $self->{sock} or return; - my $ary = $EXPMAP->{fileno($sock)} or return; - my $exp_at = $ary->[0] + $EXPTIME; - $exp_at > $now; -} - # for graceful shutdown in PublicInbox::Daemon: sub busy { my ($self, $now) = @_; - ($self->{rbuf} || $self->{wbuf} || not_idle_long($self, $now)); + ($self->{rbuf} || $self->{wbuf} || $self->not_idle_long($now)); } # this is an import to prevent "perl -c" from complaining about fields