1*cc02d7e2SAndroid Build Coastguard Worker# gRPC (Core) Compression Cookbook 2*cc02d7e2SAndroid Build Coastguard Worker 3*cc02d7e2SAndroid Build Coastguard Worker## Introduction 4*cc02d7e2SAndroid Build Coastguard Worker 5*cc02d7e2SAndroid Build Coastguard WorkerThis document describes compression as implemented by the gRPC C core. See [the 6*cc02d7e2SAndroid Build Coastguard Workerfull compression specification](compression.md) for details. 7*cc02d7e2SAndroid Build Coastguard Worker 8*cc02d7e2SAndroid Build Coastguard Worker### Intended Audience 9*cc02d7e2SAndroid Build Coastguard Worker 10*cc02d7e2SAndroid Build Coastguard WorkerWrapped languages developers, for the purposes of supporting compression by 11*cc02d7e2SAndroid Build Coastguard Workerinteracting with the C core. 12*cc02d7e2SAndroid Build Coastguard Worker 13*cc02d7e2SAndroid Build Coastguard Worker## Criteria for GA readiness 14*cc02d7e2SAndroid Build Coastguard Worker 15*cc02d7e2SAndroid Build Coastguard Worker1. Be able to set compression at [channel](#per-channel-settings), 16*cc02d7e2SAndroid Build Coastguard Worker [call](#per-call-settings) and [message](#per-message-settings) level. 17*cc02d7e2SAndroid Build Coastguard Worker In principle this API should be based on _compression levels_ as opposed to 18*cc02d7e2SAndroid Build Coastguard Worker algorithms. See the discussion [below](#level-vs-algorithms). 19*cc02d7e2SAndroid Build Coastguard Worker1. Have unit tests covering [the cases from the 20*cc02d7e2SAndroid Build Coastguard Worker spec](https://github.com/grpc/grpc/blob/master/doc/compression.md#test-cases). 21*cc02d7e2SAndroid Build Coastguard Worker1. Interop tests implemented and passing on Jenkins. The two relevant interop 22*cc02d7e2SAndroid Build Coastguard Worker test cases are 23*cc02d7e2SAndroid Build Coastguard Worker [large_compressed_unary](https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md#large_compressed_unary) 24*cc02d7e2SAndroid Build Coastguard Worker and 25*cc02d7e2SAndroid Build Coastguard Worker [server_compressed_streaming](https://github.com/grpc/grpc/blob/master/doc/interop-test-descriptions.md#server_compressed_streaming). 26*cc02d7e2SAndroid Build Coastguard Worker 27*cc02d7e2SAndroid Build Coastguard Worker## Summary Flowcharts 28*cc02d7e2SAndroid Build Coastguard Worker 29*cc02d7e2SAndroid Build Coastguard WorkerThe following flowcharts depict the evolution of a message, both _incoming_ and 30*cc02d7e2SAndroid Build Coastguard Worker_outgoing_, irrespective of the client/server character of the call. Aspects 31*cc02d7e2SAndroid Build Coastguard Workerstill not symmetric between clients and servers (e.g. the [use of compression 32*cc02d7e2SAndroid Build Coastguard Workerlevels](https://github.com/grpc/grpc/blob/master/doc/compression.md#compression-levels-and-algorithms)) 33*cc02d7e2SAndroid Build Coastguard Workerare explicitly marked. The in-detail textual description for the different 34*cc02d7e2SAndroid Build Coastguard Workerscenarios is described in subsequent sections. 35*cc02d7e2SAndroid Build Coastguard Worker 36*cc02d7e2SAndroid Build Coastguard Worker## Incoming Messages 37*cc02d7e2SAndroid Build Coastguard Worker 38*cc02d7e2SAndroid Build Coastguard Worker 39*cc02d7e2SAndroid Build Coastguard Worker 40*cc02d7e2SAndroid Build Coastguard Worker## Outgoing Messages 41*cc02d7e2SAndroid Build Coastguard Worker 42*cc02d7e2SAndroid Build Coastguard Worker 43*cc02d7e2SAndroid Build Coastguard Worker 44*cc02d7e2SAndroid Build Coastguard Worker## Levels vs Algorithms 45*cc02d7e2SAndroid Build Coastguard Worker 46*cc02d7e2SAndroid Build Coastguard WorkerAs mentioned in [the relevant discussion on the spec 47*cc02d7e2SAndroid Build Coastguard Workerdocument](https://github.com/grpc/grpc/blob/master/doc/compression.md#compression-levels-and-algorithms), 48*cc02d7e2SAndroid Build Coastguard Workercompression _levels_ are the primary mechanism for compression selection _at the 49*cc02d7e2SAndroid Build Coastguard Workerserver side_. In the future, it'll also be at the client side. The use of levels 50*cc02d7e2SAndroid Build Coastguard Workerabstracts away the intricacies of selecting a concrete algorithm supported by a 51*cc02d7e2SAndroid Build Coastguard Workerpeer, on top of removing the burden of choice from the developer. 52*cc02d7e2SAndroid Build Coastguard WorkerAs of this writing (Q2 2016), clients can only specify compression _algorithms_. 53*cc02d7e2SAndroid Build Coastguard WorkerClients will support levels as soon as an automatic retry/negotiation mechanism 54*cc02d7e2SAndroid Build Coastguard Workeris in place. 55*cc02d7e2SAndroid Build Coastguard Worker 56*cc02d7e2SAndroid Build Coastguard Worker## Per Channel Settings 57*cc02d7e2SAndroid Build Coastguard Worker 58*cc02d7e2SAndroid Build Coastguard WorkerCompression may be configured at channel creation. This is a convenience to 59*cc02d7e2SAndroid Build Coastguard Workeravoid having to repeatedly configure compression for every call. Note that any 60*cc02d7e2SAndroid Build Coastguard Workercompression setting on individual [calls](#per-call-settings) or 61*cc02d7e2SAndroid Build Coastguard Worker[messages](#per-message-settings) overrides channel settings. 62*cc02d7e2SAndroid Build Coastguard Worker 63*cc02d7e2SAndroid Build Coastguard WorkerThe following aspects can be configured at channel-creation time via channel arguments: 64*cc02d7e2SAndroid Build Coastguard Worker 65*cc02d7e2SAndroid Build Coastguard Worker#### Disable Compression _Algorithms_ 66*cc02d7e2SAndroid Build Coastguard Worker 67*cc02d7e2SAndroid Build Coastguard WorkerUse the channel argument key 68*cc02d7e2SAndroid Build Coastguard Worker`GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET` (from 69*cc02d7e2SAndroid Build Coastguard Worker[`grpc/impl/codegen/compression_types.h`](https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/compression_types.h)), 70*cc02d7e2SAndroid Build Coastguard Workertakes a 32 bit bitset value. A set bit means the algorithm with that enum value 71*cc02d7e2SAndroid Build Coastguard Workeraccording to `grpc_compression_algorithm` is _enabled_. 72*cc02d7e2SAndroid Build Coastguard WorkerFor example, `GRPC_COMPRESS_GZIP` currently has a numeric value of 2. To 73*cc02d7e2SAndroid Build Coastguard Workerenable/disable GZIP for a channel, one would set/clear the 3rd LSB (eg, 0b100 = 74*cc02d7e2SAndroid Build Coastguard Worker0x4). Note that setting/clearing 0th position, that corresponding to 75*cc02d7e2SAndroid Build Coastguard Worker`GRPC_COMPRESS_NONE`, has no effect, as no-compression (a.k.a. _identity_) is 76*cc02d7e2SAndroid Build Coastguard Workeralways supported. 77*cc02d7e2SAndroid Build Coastguard WorkerIncoming messages compressed (ie, encoded) with a disabled algorithm will result 78*cc02d7e2SAndroid Build Coastguard Workerin the call being closed with `GRPC_STATUS_UNIMPLEMENTED`. 79*cc02d7e2SAndroid Build Coastguard Worker 80*cc02d7e2SAndroid Build Coastguard Worker#### Default Compression _Level_ 81*cc02d7e2SAndroid Build Coastguard Worker 82*cc02d7e2SAndroid Build Coastguard Worker**(currently, Q2 2016, only applicable for server side channels. It's ignored 83*cc02d7e2SAndroid Build Coastguard Workerfor clients.)** 84*cc02d7e2SAndroid Build Coastguard WorkerUse the channel argument key `GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL` (from 85*cc02d7e2SAndroid Build Coastguard Worker[`grpc/impl/codegen/compression_types.h`](https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/compression_types.h)), 86*cc02d7e2SAndroid Build Coastguard Workervalued by an integer corresponding to a value from the `grpc_compression_level` 87*cc02d7e2SAndroid Build Coastguard Workerenum. 88*cc02d7e2SAndroid Build Coastguard Worker 89*cc02d7e2SAndroid Build Coastguard Worker#### Default Compression _Algorithm_ 90*cc02d7e2SAndroid Build Coastguard Worker 91*cc02d7e2SAndroid Build Coastguard WorkerUse the channel argument key `GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM` (from 92*cc02d7e2SAndroid Build Coastguard Worker[`grpc/impl/codegen/compression_types.h`](https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/compression_types.h)), 93*cc02d7e2SAndroid Build Coastguard Workervalued by an integer corresponding to a value from the `grpc_compression_level` 94*cc02d7e2SAndroid Build Coastguard Workerenum. 95*cc02d7e2SAndroid Build Coastguard Worker 96*cc02d7e2SAndroid Build Coastguard Worker## Per Call Settings 97*cc02d7e2SAndroid Build Coastguard Worker 98*cc02d7e2SAndroid Build Coastguard Worker### Compression **Level** in Call Responses 99*cc02d7e2SAndroid Build Coastguard Worker 100*cc02d7e2SAndroid Build Coastguard WorkerThe server requests a compression level via initial metadata. The 101*cc02d7e2SAndroid Build Coastguard Worker`send_initial_metadata` `grpc_op` contains a `maybe_compression_level` field 102*cc02d7e2SAndroid Build Coastguard Workerwith two fields, `is_set` and `compression_level`. The former must be set when 103*cc02d7e2SAndroid Build Coastguard Workeractively choosing a level to disambiguate the default value of zero (no 104*cc02d7e2SAndroid Build Coastguard Workercompression) from the proactive selection of no compression. 105*cc02d7e2SAndroid Build Coastguard Worker 106*cc02d7e2SAndroid Build Coastguard WorkerThe core will receive the request for the compression level and automatically 107*cc02d7e2SAndroid Build Coastguard Workerchoose a compression algorithm based on its knowledge about the peer 108*cc02d7e2SAndroid Build Coastguard Worker(communicated by the client via the `grpc-accept-encoding` header. Note that the 109*cc02d7e2SAndroid Build Coastguard Workerabsence of this header means no compression is supported by the client/peer). 110*cc02d7e2SAndroid Build Coastguard Worker 111*cc02d7e2SAndroid Build Coastguard Worker### Compression **Algorithm** in Call Responses 112*cc02d7e2SAndroid Build Coastguard Worker 113*cc02d7e2SAndroid Build Coastguard Worker**Server should avoid setting the compression algorithm directly**. Prefer 114*cc02d7e2SAndroid Build Coastguard Workersetting compression levels unless there's a _very_ compelling reason to choose 115*cc02d7e2SAndroid Build Coastguard Workerspecific algorithms (benchmarking, testing). 116*cc02d7e2SAndroid Build Coastguard Worker 117*cc02d7e2SAndroid Build Coastguard WorkerSelection of concrete compression algorithms is performed by adding a 118*cc02d7e2SAndroid Build Coastguard Worker`(GRPC_COMPRESS_REQUEST_ALGORITHM_KEY, <algorithm-name>)` key-value pair to the 119*cc02d7e2SAndroid Build Coastguard Workerinitial metadata, where `GRPC_COMPRESS_REQUEST_ALGORITHM_KEY` is defined in 120*cc02d7e2SAndroid Build Coastguard Worker[`grpc/impl/codegen/compression_types.h`](https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/compression_types.h)), 121*cc02d7e2SAndroid Build Coastguard Workerand `<algorithm-name>` is the human readable name of the algorithm as given in 122*cc02d7e2SAndroid Build Coastguard Worker[the HTTP2 spec](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md) 123*cc02d7e2SAndroid Build Coastguard Workerfor `Message-Encoding` (e.g. gzip, identity, etc.). See 124*cc02d7e2SAndroid Build Coastguard Worker[`grpc_compression_algorithm_name`](https://github.com/grpc/grpc/blob/master/src/core/lib/compression/compression.c) 125*cc02d7e2SAndroid Build Coastguard Workerfor the mapping between the `grpc_compression_algorithm` enum values and their 126*cc02d7e2SAndroid Build Coastguard Workertextual representation. 127*cc02d7e2SAndroid Build Coastguard Worker 128*cc02d7e2SAndroid Build Coastguard Worker## Per Message Settings 129*cc02d7e2SAndroid Build Coastguard Worker 130*cc02d7e2SAndroid Build Coastguard WorkerTo disable compression for a specific message, the `flags` field of `grpc_op` 131*cc02d7e2SAndroid Build Coastguard Workerinstances of type `GRPC_OP_SEND_MESSAGE` must have its `GRPC_WRITE_NO_COMPRESS` 132*cc02d7e2SAndroid Build Coastguard Workerbit set. Refer to 133*cc02d7e2SAndroid Build Coastguard Worker[`grpc/impl/codegen/compression_types.h`](https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/compression_types.h)), 134