Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expected semantics of grpc-encoding and grpc-accept-encoding headers? #2749

Closed
akshayjshah opened this issue Apr 5, 2019 · 2 comments
Closed

Comments

@akshayjshah
Copy link

akshayjshah commented Apr 5, 2019

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-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 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.

@akshayjshah
Copy link
Author

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.

@menghanl
Copy link
Contributor

Right, the support of grpc-accept-encoding is missing in gRPC-go. I've filed #2786 to track.
Thanks a lot for pointing this out!

@lock lock bot locked as resolved and limited conversation to collaborators Oct 20, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants