[PATCH] hgweb: config option to control zlib compression level

Gregory Szorc gregory.szorc at gmail.com
Mon Aug 8 01:12:37 UTC 2016


# HG changeset patch
# User Gregory Szorc <gregory.szorc at gmail.com>
# Date 1470618598 25200
#      Sun Aug 07 18:09:58 2016 -0700
# Node ID d5e9dedbc7f912ff2dc2e92586347250aee11ac2
# Parent  3ef9aa7ad1fc4c43b92d48e4bb1f4e3de68b6910
hgweb: config option to control zlib compression level

Before this patch, the HTTP transport protocol would always zlib
compress certain responses (notably "getbundle" wire protocol commands)
at zlib compression level 6.

zlib can be a massive CPU resource sink for servers. Some server
operators may wish to reduce server-side CPU requirements while
requiring more bandwidth. This is common on corporate intranets, for
example. Others may wish to use more CPU but reduce bandwidth.

This patch introduces a config option to allow server operators
to control the zlib compression level.

On the "mozilla-unified" generaldelta repository, setting this
value to "0" (disable compression) results in server-side CPU
utilization for a `hg clone` going from ~180s to ~124s CPU time on
my i7-6700K.  A level of "1" (which increases the transfer size from
~1,074 MB at level 6 to ~1,222 MB) utilizes ~132s CPU time.

diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt
--- a/mercurial/help/config.txt
+++ b/mercurial/help/config.txt
@@ -1552,16 +1552,31 @@ Controls generic server settings.
     Like ``bundle1.pull`` but only used if the repository is using the
     *generaldelta* storage format. (default: True)
 
     Large repositories using the *generaldelta* storage format should
     consider setting this option because converting *generaldelta*
     repositories to the exchange format required by the bundle1 data
     format can consume a lot of CPU.
 
+``zliblevel``
+    Integer between ``-1`` and ``9`` that controls the zlib compression level
+    for wire protocol commands that send zlib compressed output (notably the
+    commands that send repository history data).
+
+    The default (``-1``) uses the default zlib compression level, which is
+    likely equivalent to ``6``. ``0`` means no compression. ``9`` means
+    maximum compression.
+
+    Setting this option allows server operators to make trade-offs between
+    bandwidth and CPU used. Lowering the compression lowers CPU utilization
+    but sends more bytes to clients.
+
+    This option only impacts the HTTP server.
+
 ``smtp``
 --------
 
 Configuration for extensions that need to send email messages.
 
 ``host``
     Host name of mail server, e.g. "mail.example.com".
 
diff --git a/mercurial/hgweb/protocol.py b/mercurial/hgweb/protocol.py
--- a/mercurial/hgweb/protocol.py
+++ b/mercurial/hgweb/protocol.py
@@ -69,17 +69,17 @@ class webproto(wireproto.abstractserverp
     def redirect(self):
         self.oldio = self.ui.fout, self.ui.ferr
         self.ui.ferr = self.ui.fout = stringio()
     def restore(self):
         val = self.ui.fout.getvalue()
         self.ui.ferr, self.ui.fout = self.oldio
         return val
     def groupchunks(self, cg):
-        z = zlib.compressobj()
+        z = zlib.compressobj(self.ui.configint('server', 'zliblevel', -1))
         while True:
             chunk = cg.read(4096)
             if not chunk:
                 break
             yield z.compress(chunk)
         yield z.flush()
     def _client(self):
         return 'remote:%s:%s:%s' % (


More information about the Mercurial-devel mailing list