about summary refs log tree commit homepage
path: root/lib/PublicInbox/NNTP.pm
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2019-07-05 22:53:39 +0000
committerEric Wong <e@80x24.org>2019-07-06 04:33:39 +0000
commita3c054cbbf2a51be121b3237c5d223acc5c8a2f4 (patch)
tree7ea4e22652ad3063d6cc84c39a3aec4cacbf4eb6 /lib/PublicInbox/NNTP.pm
parent77c66b4cdb1d52321ed3cb6352fe0b72312cbb71 (diff)
downloadpublic-inbox-a3c054cbbf2a51be121b3237c5d223acc5c8a2f4.tar.gz
Using Z_FULL_FLUSH at the right places in our event loop, it
appears we can share a single zlib deflate context across ALL
clients in a process.

The zlib deflate context is the biggest factor in per-client
memory use, so being able to share that across many clients
results in a large memory savings.

With 10K idle-but-did-something NNTP clients connected to a
single process on a 64-bit system, TLS+DEFLATE used around
1.8 GB of RSS before this change.  It now uses around 300 MB.
TLS via IO::Socket::SSL alone uses <200MB in the same situation,
so the actual memory reduction is over 10x.

This makes compression less efficient and bandwidth increases
around 45% in informal testing, but it's far better than no
compression at all.  It's likely around the same level of
compression gzip gives on the HTTP side.

Security implications with TLS?  I don't know, but I don't
really care, either...  public-inbox-nntpd doesn't support
authentication and it's up to the client to enable compression.
It's not too different than Varnish caching gzipped responses
on the HTTP side and having responses go to multiple HTTPS
clients.
Diffstat (limited to 'lib/PublicInbox/NNTP.pm')
-rw-r--r--lib/PublicInbox/NNTP.pm7
1 files changed, 7 insertions, 0 deletions
diff --git a/lib/PublicInbox/NNTP.pm b/lib/PublicInbox/NNTP.pm
index d6f315ba..895858b7 100644
--- a/lib/PublicInbox/NNTP.pm
+++ b/lib/PublicInbox/NNTP.pm
@@ -642,6 +642,11 @@ sub long_response ($$) {
                 } elsif ($more) { # $self->{wbuf}:
                         update_idle_time($self);
 
+                        # COMPRESS users all share the same DEFLATE context.
+                        # Flush it here to ensure clients don't see
+                        # each other's data
+                        $self->zflush;
+
                         # no recursion, schedule another call ASAP
                         # but only after all pending writes are done
                         my $wbuf = $self->{wbuf} ||= [];
@@ -925,6 +930,8 @@ sub cmd_compress ($$) {
         undef
 }
 
+sub zflush {} # overridden by NNTPdeflate
+
 sub cmd_xpath ($$) {
         my ($self, $mid) = @_;
         return r501 unless $mid =~ /\A<(.+)>\z/;