]> Sergey Matveev's repositories - public-inbox.git/commitdiff
gzipfilter: lazy allocate the deflate context
authorEric Wong <e@yhbt.net>
Sat, 21 Mar 2020 02:03:45 +0000 (02:03 +0000)
committerEric Wong <e@yhbt.net>
Wed, 25 Mar 2020 01:48:35 +0000 (01:48 +0000)
zlib contexts are memory-intensive, particularly when used for
compression.  Since the gzip filter may be sitting in a limiter
queue for a long period, delay the allocation we actually have
data to translate, and not a moment sooner.

lib/PublicInbox/GzipFilter.pm

index d883130f39f7fb1cb938ffa6435175d679cc3fd4..864095862096f423ed0d02e2214087515b60673c 100644 (file)
@@ -8,11 +8,7 @@ use bytes (); # length
 use Compress::Raw::Zlib qw(Z_FINISH Z_OK);
 my %OPT = (-WindowBits => 15 + 16, -AppendOutput => 1);
 
-sub new {
-       my ($gz, $err) = Compress::Raw::Zlib::Deflate->new(%OPT);
-       $err == Z_OK or die "Deflate->new failed: $err";
-       bless { gz => $gz }, shift;
-}
+sub new { bless {}, shift }
 
 # for Qspawn if using $env->{'pi-httpd.async'}
 sub attach {
@@ -24,6 +20,15 @@ sub attach {
 # for GetlineBody (via Qspawn) when NOT using $env->{'pi-httpd.async'}
 sub translate ($$) {
        my $self = $_[0];
+
+       # allocate the zlib context lazily here, instead of in ->new.
+       # Deflate contexts are memory-intensive and this object may
+       # be sitting in the Qspawn limiter queue for a while.
+       my $gz = $self->{gz} ||= do {
+               my ($g, $err) = Compress::Raw::Zlib::Deflate->new(%OPT);
+               $err == Z_OK or die "Deflate->new failed: $err";
+               $g;
+       };
        my $zbuf = delete($self->{zbuf});
        if (defined $_[1]) { # my $buf = $_[1];
                my $err = $self->{gz}->deflate($_[1], $zbuf);