Skip to content
Snippets Groups Projects
  • Gregory Szorc's avatar
    e75463e3
    protocol: send application/mercurial-0.2 responses to capable clients · e75463e3
    Gregory Szorc authored
    With this commit, the HTTP transport now parses the X-HgProto-<N>
    header to determine what media type and compression engine to use for
    responses. So far, we only compress responses that are already being
    compressed with zlib today (stream response types to specific
    commands). We can expand things to cover additional response types
    later.
    
    The practical side-effect of this commit is that non-zlib compression
    engines will be used if both ends support them. This means if both
    ends have zstd support, zstd - not zlib - will be used to compress
    data!
    
    When cloning the mozilla-unified repository between a local HTTP
    server and client, the benefits of non-zlib compression are quite
    noticeable:
    
      engine     server CPU (s)   client CPU (s)    bundle size
    zlib (l=6)      174.1            283.2         1,148,547,026
    zstd (l=1)       99.2            267.3         1,127,513,841
    zstd (l=3)      103.1            266.9         1,018,861,363
    zstd (l=7)      128.3            269.7           919,190,278
    zstd (l=10)     162.0               -            894,547,179
    none             95.3            277.2         4,097,566,064
    
    The default zstd compression level is 3. So if you deploy zstd
    capable Mercurial to your clients and servers and CPU time on
    your server is dominated by "getbundle" requests (clients cloning
    and pulling) - and my experience at Mozilla tells me this is often
    the case - this commit could drastically reduce your server-side
    CPU usage *and* save on bandwidth costs!
    
    Another benefit of this change is that server operators can install
    *any* compression engine. While it isn't enabled by default, the
    "none" compression engine can now be used to disable wire protocol
    compression completely. Previously, commands like "getbundle" always
    zlib compressed output, adding considerable overhead to generating
    responses. If you are on a high speed network and your server is under
    high load, it might be advantageous to trade bandwidth for CPU.
    Although, zstd at level 1 doesn't use that much CPU, so I'm not
    convinced that disabling compression wholesale is worthwhile. And, my
    data seems to indicate a slow down on the client without compression.
    I suspect this is due to a lack of buffering resulting in an increase
    in socket read() calls and/or the fact we're transferring an extra 3 GB
    of data (parsing HTTP chunked transfer and processing extra TCP packets
    can add up). This is definitely worth investigating and optimizing. But
    since the "none" compressor isn't enabled by default, I'm inclined to
    punt on this issue.
    
    This commit introduces tons of tests. Some of these should arguably
    have been implemented on previous commits. But it was difficult to
    test without the server functionality in place.
    e75463e3
    History
    protocol: send application/mercurial-0.2 responses to capable clients
    Gregory Szorc authored
    With this commit, the HTTP transport now parses the X-HgProto-<N>
    header to determine what media type and compression engine to use for
    responses. So far, we only compress responses that are already being
    compressed with zlib today (stream response types to specific
    commands). We can expand things to cover additional response types
    later.
    
    The practical side-effect of this commit is that non-zlib compression
    engines will be used if both ends support them. This means if both
    ends have zstd support, zstd - not zlib - will be used to compress
    data!
    
    When cloning the mozilla-unified repository between a local HTTP
    server and client, the benefits of non-zlib compression are quite
    noticeable:
    
      engine     server CPU (s)   client CPU (s)    bundle size
    zlib (l=6)      174.1            283.2         1,148,547,026
    zstd (l=1)       99.2            267.3         1,127,513,841
    zstd (l=3)      103.1            266.9         1,018,861,363
    zstd (l=7)      128.3            269.7           919,190,278
    zstd (l=10)     162.0               -            894,547,179
    none             95.3            277.2         4,097,566,064
    
    The default zstd compression level is 3. So if you deploy zstd
    capable Mercurial to your clients and servers and CPU time on
    your server is dominated by "getbundle" requests (clients cloning
    and pulling) - and my experience at Mozilla tells me this is often
    the case - this commit could drastically reduce your server-side
    CPU usage *and* save on bandwidth costs!
    
    Another benefit of this change is that server operators can install
    *any* compression engine. While it isn't enabled by default, the
    "none" compression engine can now be used to disable wire protocol
    compression completely. Previously, commands like "getbundle" always
    zlib compressed output, adding considerable overhead to generating
    responses. If you are on a high speed network and your server is under
    high load, it might be advantageous to trade bandwidth for CPU.
    Although, zstd at level 1 doesn't use that much CPU, so I'm not
    convinced that disabling compression wholesale is worthwhile. And, my
    data seems to indicate a slow down on the client without compression.
    I suspect this is due to a lack of buffering resulting in an increase
    in socket read() calls and/or the fact we're transferring an extra 3 GB
    of data (parsing HTTP chunked transfer and processing extra TCP packets
    can add up). This is definitely worth investigating and optimizing. But
    since the "none" compressor isn't enabled by default, I'm inclined to
    punt on this issue.
    
    This commit introduces tons of tests. Some of these should arguably
    have been implemented on previous commits. But it was difficult to
    test without the server functionality in place.