You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
To better understand gRPC, I've been writing a toy implementation using x/net/http2 and the stdlib's net/http. It's going pretty well, mostly because your HTTP/2 specification is great - thank you for producing such a short, readable document! 🙇 However, I'm having trouble understanding how the grpc-encoding and grpc-accept-encoding headers are intended to work.
From the portion of the request spec on length-prefixed messages, it sounds like grpc-encoding describes the compression used for the sender's side of the current message exchange. That's simple enough: the client sends grpc-encoding = gzip and zips its length-prefixed messages. There's no discussion of encodings in the response section, but I assume that the server should default to the same encoding as the client (and send the same grpc-encoding = gzip header).
That assumption matches the example request/response exchange, where the client uses gzip for the request and the server uses gzip for the response. Neither party sends grpc-accept-encoding. When the client is sure that the server supports a particular encoding, this seems straightforward.
Can servers compress the response to an uncompressed request? I assume that this is what the grpc-accept-encoding header is for, but the specification only describes the grammar of the header - it doesn't cover behavior. From what I can see, the grpc-go implementation doesn't ever send or read grpc-accept-encoding. grpc-javadoes read this header, and it has a test for encodings which suggests that there's some negotiation happening. Unfortunately, my Java is so bad that I'm having trouble following the logic of the test. 😢
Doesn't grpc-go's current behavior make it hard to use anything other than the identity encoding? Clients need to know a priori that the server they're talking to supports a particular compression algorithm, and if they're wrong they'll need to retry at the application layer.
Reading the specification, I expected something more like HTTP's Content-Encoding and Accept-Encoding - unless they're sure that the server supports a particular encoding, clients use identity and advertise their own encoding support using grpc-accept-encoding. Servers then choose which of the client-supported encodings they'd like to use for the response, taking into account whatever factors they'd like (payload size, current network I/O, CPU load, etc). This seems like a win for both parties: since most production clients and servers support gzip and/or snappy, more traffic can be compressed without needing application-level retries or offline collaboration between programmers. Where request payloads are large or traffic is in a closed, predictable ecosystem, clients can still opt into compressed requests.
Boiling all this down:
Am I correct in my interpretation of the specification?
Can we clarify the specification a bit? (Happy to open a PR if so.)
Should grpc-go always send the names of all registered compressors in grpc-accept-encoding (for both requests and responses)?
Where possible, should grpc-go servers compress responses to uncompressed requests?
🙏 Thanks for entertaining my protocol questions! 🙏 Feel free to redirect me if this discussion should be happening in another gRPC repository.
The text was updated successfully, but these errors were encountered:
Ah, I found compression.md in the grpc docs folder - that clarifies most of these points. I'm surprised that grpc-go doesn't send grpc-accept-encoding, but that's a separate issue.
To better understand gRPC, I've been writing a toy implementation using
x/net/http2
and the stdlib'snet/http
. It's going pretty well, mostly because your HTTP/2 specification is great - thank you for producing such a short, readable document! 🙇 However, I'm having trouble understanding how thegrpc-encoding
andgrpc-accept-encoding
headers are intended to work.grpc-encoding
describes the compression used for the sender's side of the current message exchange. That's simple enough: the client sendsgrpc-encoding = gzip
and zips its length-prefixed messages. There's no discussion of encodings in the response section, but I assume that the server should default to the same encoding as the client (and send the samegrpc-encoding = gzip
header).gzip
for the request and the server usesgzip
for the response. Neither party sendsgrpc-accept-encoding
. When the client is sure that the server supports a particular encoding, this seems straightforward.grpc-accept-encoding
header is for, but the specification only describes the grammar of the header - it doesn't cover behavior. From what I can see, thegrpc-go
implementation doesn't ever send or readgrpc-accept-encoding
.grpc-java
does read this header, and it has a test for encodings which suggests that there's some negotiation happening. Unfortunately, my Java is so bad that I'm having trouble following the logic of the test. 😢Doesn't
grpc-go
's current behavior make it hard to use anything other than theidentity
encoding? Clients need to know a priori that the server they're talking to supports a particular compression algorithm, and if they're wrong they'll need to retry at the application layer.Reading the specification, I expected something more like HTTP's
Content-Encoding
andAccept-Encoding
- unless they're sure that the server supports a particular encoding, clients useidentity
and advertise their own encoding support usinggrpc-accept-encoding
. Servers then choose which of the client-supported encodings they'd like to use for the response, taking into account whatever factors they'd like (payload size, current network I/O, CPU load, etc). This seems like a win for both parties: since most production clients and servers supportgzip
and/orsnappy
, more traffic can be compressed without needing application-level retries or offline collaboration between programmers. Where request payloads are large or traffic is in a closed, predictable ecosystem, clients can still opt into compressed requests.Boiling all this down:
grpc-go
always send the names of all registered compressors ingrpc-accept-encoding
(for both requests and responses)?grpc-go
servers compress responses to uncompressed requests?🙏 Thanks for entertaining my protocol questions! 🙏 Feel free to redirect me if this discussion should be happening in another gRPC repository.
The text was updated successfully, but these errors were encountered: