Hacker News new | ask | show | jobs
by vidarh 1417 days ago
Another option is simply to reserve a key (or multiple) for providing stream/transport specific metadata which should be stripped out before handoff to the client, such as allowing you to send an "end" marker. Now you're not depending on the transport layer cooperating. It's not a particularly hard problem.
1 comments

That has the downside that you're now limiting what protobuf payloads you can send. You need to have the inner protocol (protobuf) cooperate with the outer protocol. That also makes it difficult to switch to a different type of payload besides protobuf, since even if you could convince the protobuf standard to reserve a specific key for the outer protocol, you might not be able to convince the standard for a different protocol to reserve that for you. The article says "gRPC is definitely not Protobuf specific".

It's like an intrusive linked list vs std::list. Sure you can do intrusive linked lists, but it means you have to clutter up your object with info about how it's stored. It mixes the layers.

I think most people would say that not being able to use GRPC at all on the web is not exactly the superior option/outcome ... I'm not sure why a "pure design" (non-mixed layers) matters when the result is non-functional.

Just open a second websocket for the second protocol. Or use WebRTC. Or ... most protocols have these channels, which means mixing payloads is not really that useful. It doesn't buy you anything over the situation where you're not mixing protocols.

I'm not saying the current situation is better than your suggestion. I'm saying there are better ways to fix the current situation than your suggestion.

My idea of a better way would be:

* If you just need a boolean of success vs failure: use END_STREAM vs RST_STREAM.

* If you additionally need metadata of failure reason: use the existing length prefixes that gRPC has, and additionally add a bit to indicate data vs trailer. Then implement your own trailers inside the HTTP2 stream to indicate success vs failure and failure reason. Sure these trailers won't get HTTP2 compression like native HTTP2 trailers, but that shouldn't be a big problem.

Using 2 websockets would be confusing because things could arrive out of order from how they were sent. And one websocket could fail but not the other, leading to a confusing mixed state. The whole reason for trailers was to make failures less confusing by having error messages in them.

Also, using websockets goes against the whole gRPC design idea. They wanted native HTTP2. We don't need websockets to fix the problem, we just need to implement trailers inside the stream instead of using native HTTP2 trailers. Implementing trailers inside the stream can be done with native HTTP2 streams or with websockets inside HTTP2 streams. It's a smaller change from the current protocol to put the trailers inside the native HTTP2 stream than to add websockets to the mix then implement trailers inside that.