Live data from Hacker News

Why does gRPC insist on trailers?

carlmastrangelo.com

71–80 of 136 posts

Re: Why does gRPC insist on trailers?

#71
post #65

Earlier quoted context omitted.

> It is obvious for the peer if a complete message (inside a stream or single response) is received If I'm reading [1] correctly, you can't distinguish between [repeated element X is empty] and [message truncated before repeated element X was received] because "A packed repeated field containing zero elements does not appear in the encoded message." You'd need X to be the last part of the message but that's not a pro…

Yes, the protobuf format makes the end ambiguous, meaning the end needs to be indicated by the protocol containing the protobuf. But it looks to me like the gRPC spec says that everything must be prefixed by a length at the gRPC layer. So then it doesn't matter that protobuf doesn't internally indicate the end, since the gRPC transport will indicate the end. https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2…

Yes - that’s the length prefixing I was talking about. I should prevent any disambiguities.

But even without that peers should be able to distinguish between truncated and full messages: HTTP2 allows to finish streams either cleanly or reset them. I’m case of a clean close (FIN) no truncation should be expected. I’m case of a HTTP/2 Reset or a tcp connection breakdown the stream must be treated as potentially truncated.

Re: Why does gRPC insist on trailers?

#72
post #55

Earlier quoted context omitted.

As a Googler, it's worse. Even within one of the "companies" there is distrust in the chain of command.

Googler here. Yeah, it goes my boss, another guy I'm somewhat familiar with, then some cloud of VPs or something and then Sundar. I have no idea what those vp's are up to and not much faith in their decisions.

When I joined I found it funny you can't DM Sundar. But you can DM SVPs. At least the SVP of my division is open on the chat app.

Re: Why does gRPC insist on trailers?

#73
post #58
post #48

Earlier quoted context omitted.

Sure, that's fair enough. But I'm not sure if characterizing this feature as a pet feature of the gRPC team is accurate either - after all, it's simply exposing an HTTP 1.1 & H2 feature, and it was already in the WHATWG fetch spec. There, the security concerns were apparently discussed as well [1], and adding the trailer headers as a separate object was deemed safe. I haven't read the entire discussion and don't have…

This could be solved without trailers by piggybacking on top of server sent events rather than requests with trailers, and terminating a stream with status metadata as a final event.

Server sent events are just a potential payload format for response bodies, which allows to encode a potentially infinite amount of distinct messages. Trailers are a different concept since they exist outside of bodies.

If the team had decided to only use http body streams for all payload, they could totally have done that without directly using SSE encoding.

Re: Why does gRPC insist on trailers?

#74
The author also posted an interesting Twitter thread a few months ago [0], on the day my coworkers and I posted here about our gRPC-compatible RPC framework [1]. I was a bit afraid to read this post, but I shouldn't have been - the author's a class act, and he never called us out explicitly. There's not much written about what the gRPC team was _thinking_ when they wrote up the protocol, and this was a nice window into how contemporaneous changes to HTTP and the fetch API shaped their approach. Given my current work, the final section ("Lessons for Designers") really hit home.

That said, I didn't follow the central argument - that you need HTTP trailers to detect incomplete protobuf messages. What's not mentioned in the blog post is that gRPC wraps every protobuf message in a 5-byte envelope, and the bulk of the envelope is devoted to specifying the length of the enclosed message. It's easy to detect prematurely terminated messages, because they don't contain the promised number of bytes. The author says, "[i]t’s not hard to imagine that trailers would be less of an issue, if the default encoding was JSON," because JSON objects are explicitly terminated by a closing } - but it seems to me that envelopes solve that problem neatly.

With incomplete message detection handled, we're left looking for some mechanism to detect streams that prematurely terminate at a message boundary. (This is more likely than you might expect, since servers often crash at message boundaries.) In practice, gRPC implementations already buffer responses to unary RPCs. It's therefore easy to use the standard HTTP Content-Length header for unary responses. This covers the vast majority of RPCs with a simple, uncontroversial approach. Streaming responses do need some trailer-like mechanism, but not to detect premature termination - as long as we're restricting ourselves to HTTP/2, cleanly terminated streams always end with a frame with the end of stream bit set. Streaming does need some trailer-like mechanism to send the details of any errors that occur mid-stream, but there's no need to use HTTP trailers. As the author hints, there's some unused space in the message envelope - we can use one bit to flag the last message in the stream and use it for the end-of-stream metadata. This is, more or less, what the gRPC-Web protocol is. (Admittedly, it's probably a bad idea to rely on _every_ HTTP server and proxy on the internet handling premature termination correctly. We need some sort of trailer-like construct anyways, and the fact that it also improves robustness is a nice extra benefit.)

So from the outside, it doesn't seem like trailers improve the robustness of most RPCs. Instead, it seems like the gRPC protocol prioritizes some abstract notion of cleanliness over simplicity in practice: by using the same wire protocol for unary and streaming RPCs, everyday request-response workloads take on all the complexity of streaming. Even for streaming responses, the practical difficulties of working with HTTP trailers have also been apparent for years; I'm shocked that more of the gRPC ecosystem hasn't followed .NET's lead and integrated gRPC-Web support into servers. (If I had to guess, it's difficult because many of Google's gRPC implementations include their own HTTP/2 transport - adding HTTP/1.1 support is a tremendous expansion in scope. Presumably the same applies to HTTP/3, once it's finalized.)

Again, though, I appreciated the inside look into the gRPC team's thinking. It takes courage to discuss the imperfections of your own work, especially when your former coworkers are still supporting the project. gRPC is far from perfect, but the engineers working on it are clearly skilled, experienced, and generally decent people. Hats off to the author - personally, I hope to someday write code influential enough that a retrospective makes the front page of HN :)

0: https://twitter.com/CarlMastrangelo/status/15322565762742435...

1: https://news.ycombinator.com/item?id=31584555

Re: Why does gRPC insist on trailers?

#75
post #8

Author doesn't support the case for grpc being a "failure". I wonder by what measure. It's certainly pretty popular.

I was going to post a similar comment, but looking back at the post I realised that the author is upfront about what they consider the original point of gRPC to be:

> gRPC was reared by two parents trying to solve similar problems:

> 1. The Stubby team. They had just begun the next iteration of their RPC system...

> 2. The API team. ... serving (all) public APIs at Google ... [this is not said explicitly but presumably the vast majority of API clients are web based]

As you say, gPRC is very popular at server messaging, but I suppose it can never be an API solution. So, even if gRPC is successful in general, it was not successful at its original goal (as far as this author is concerned).

Re: Why does gRPC insist on trailers?

#76
Personal opinion: RPC is a failed architectural style, independent of what serialization/marshalling of arguments is used. it failed with CORBA, it failed with ONC-RPC, it failed with Java RMI.

Remote Procedure Calls attempt to abstract away the networked nature of the function and make it "look like" a local function call. That's Just Wrong. When two networked services are communicating, the network must be considered.

REST relies on the media type, links and the limited verb set to define the resource and the state transfer operations to change the state of the resource.

HTTP explicitly incorporates the networked nature of the server/client relationship, independent of, and irrespective of, the underlying server or client implementation.

Media types, separated from the HTTP networking, define the format and serialization of the resource representation independent of the network.

HTTP/REST doesn't really support streaming.

Re: Why does gRPC insist on trailers?

#77
post #64
post #47

Earlier quoted context omitted.

He offers two facts that I think explain this well enough: > Additionally, they chose to keep Protobuf as the default wire format, but allow other encodings too. And: > Since streaming is a primary feature of gRPC, we often will not know the length of the response ahead of time. These make sense; you'd enable servers to start streaming back the responses directly as they were generating them, before the length of the…

This doesn't match what I see in the gRPC spec. It says every message must be length-prefixed. https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.... Disclaimer: I don't know much about gRPC.

I've spent a fair bit of time working with gRPC, and you're correct - gRPC's length-prefixing makes it easy to detect when individual messages are terminated early. You do still need some way to detect streams that terminate unexpectedly on message boundaries - perhaps you could rely on HTTP/2 EOS bits as evidence of an application-level success, but you need some equivalent of trailers to communicate the details of any errors that occur midway through the response stream anyways.

Re: Why does gRPC insist on trailers?

#78
post #53

I use GRPC between micro services instead of REST and for that it is really great; All the deficiencies of REST - Non versioned, no typed goes away with GRPC and the protobuf is the official interface for all micro-services. No problems with this approach for over two years now; and also multi language support - We have Go and Java and Python and TypeScript micro-services now happily talking and getting new features…

This is more or less what stubby is/was for Google and so the original driving force in implementing it. Now, if you add a catch all service that translates the requests from the outside to Protobuffers and then forwards the translated requests to the correct service you have a GFE (Google Front-End) equivalent.

Should you do it? Probably not as it's not just a dumb translation layer and it is extremely complex (e.g. needs to support streams which is non-trivial in this situation). For Google it's worth because this way you only have to handle protobuffers beyond the GFE layer.

Re: Why does gRPC insist on trailers?

#79
post #52

From my perspective, I think the biggest issue with gRPC is it using HTTP/2. I understand that there’s a lot of reasons to say “No, HTTP/2 is far superior to HTTP/1.1.” However, in terms of proxying _outside Google_ HTTP/2 has lagged, and continues to lags at the L7 proxy layer. I recently performed a lot of high-throughput proxying comparing HAProxy, Traefik, and Envoy. HTTP/1.1 outperformed HTTP/2 (even H2C) by a p…

Also, http/2 over cleartext is not very well supported by a lot of things. Which is probably a good thing when going over the open internet. But it means you have to deal with setting up certificates even if just developing locally, and makes it more difficult to use for IPC on a single host.

My preferred setup is to have an unencrypted service running on 127.0.0.1 (so not publicly available), and then have nginx in front to handle certificates. Lets me do all certificate stuff across all virtual hosts in one place. HTTP/2 makes this impossible due to its ridiculous TLS requirement, so I, and everyone who does it the way I do, must keep using HTTP/1.1 forever.

It's my belief that requiring TLS for HTTP/2 is what killed the protocol. It just causes too much friction during both development and deployment, for little to no (or negative) performance gain.

Re: Why does gRPC insist on trailers?

#80

Relevant post from a few days ago: Connect-Web: TypeScript library for calling RPC servers from web browsers https://news.ycombinator.com/item?id=32345670 I’m curious if anyone knows how Google internally works around the lack of support for gRPC in the browser? Perhaps gRPC is not used for public APIs? The lack of browser support in the protobuf and gRPC ecosystem was quite surprising and one of the biggest drawback…

Back in the day, it wasn't used for private API's either. Different teams had come up with different ways of encoding protobuf-style messages as JSON for web apps. For the best browser-side performance, usually you want to use browser's native JSON.parse() API call and this doesn't really let you use unmodified protobufs. In particular, you can't use 64-bit ints since that's not a native JavaScript type. Meanwhile, s…

Is decoding performance typically a problem for web UIs? The lackluster performance of binary protobuf decoding in browsers (and unmarshaling BigInts from JSON) seems much less problematic than (1) using a 200 for unary error responses, (2) choosing a wire format that's _always_ opaque to the network inspector tab, and (3) having really poor generated code.

> It didn't seem like the gRPC folks understood the needs of web developers very well.

Agreed. Being fair to the team that designed the protocol, though, it seems like browsers weren't in scope at the time.

Post reply on HN