]> Sergey Matveev's repositories - public-inbox.git/commitdiff
nntp: lazily allocate and stash rbuf
authorEric Wong <e@80x24.org>
Mon, 24 Jun 2019 02:52:50 +0000 (02:52 +0000)
committerEric Wong <e@80x24.org>
Mon, 24 Jun 2019 05:26:27 +0000 (05:26 +0000)
Allocating a per-client buffer up front is unnecessary and
wastes a hash slot.  For the majority of (non-malicious)
clients, we won't need to store rbuf in a long-lived object
associated with a client socket at all.

This saves around 10M on 64-bit with 20K connected-but-idle
clients.

lib/PublicInbox/NNTP.pm

index 6acfcc1bd793ea581aae6ac3bc59d3c527da6762..10a2e158fe739ff171d8ccff4cff2654e5f0f499 100644 (file)
@@ -107,7 +107,6 @@ sub new ($$$) {
        $self->{nntpd} = $nntpd;
        push @$wbuf, \&greet;
        $self->{wbuf} = $wbuf;
-       $self->{rbuf} = '';
        update_idle_time($self);
        $expt ||= PublicInbox::EvCleanup::later(*expire_old);
        $self;
@@ -964,7 +963,7 @@ sub event_step {
        # otherwise we can be buffering infinitely w/o backpressure
 
        use constant LINE_MAX => 512; # RFC 977 section 2.3
-       my $rbuf = \($self->{rbuf});
+       my $rbuf = $self->{rbuf} // (\(my $x = ''));
        my $r = 1;
 
        if (index($$rbuf, "\n") < 0) {
@@ -984,6 +983,11 @@ sub event_step {
        return $self->close if $r < 0;
        my $len = bytes::length($$rbuf);
        return $self->close if ($len >= LINE_MAX);
+       if ($len) {
+               $self->{rbuf} = $rbuf;
+       } else {
+               delete $self->{rbuf};
+       }
        update_idle_time($self);
 
        # maybe there's more pipelined data, or we'll have
@@ -1002,7 +1006,7 @@ sub not_idle_long ($$) {
 # for graceful shutdown in PublicInbox::Daemon:
 sub busy {
        my ($self, $now) = @_;
-       ($self->{rbuf} ne '' || $self->{wbuf} || not_idle_long($self, $now));
+       ($self->{rbuf} || $self->{wbuf} || not_idle_long($self, $now));
 }
 
 1;