- Author(s): ncteisen
- Approver: vjpai
- Status: Draft
- Implemented in: grpc/grpc#15771
- Last updated: 2018-07-01
- Discussion at: https://groups.google.com/forum/#!topic/grpc-io/3FTSA67iios
This document proposes adding a new API to the C++ generated code layer for servers. This API would designate that the selected methods be handled in a raw manner, which means that their signatures will be written in terms of ::grpc::ByteBuffer
as opposed to API specific protobuf objects.
Many teams have expressed interest in having a proto defined service that has some specialized methods that do custom serialization. The need for this use case has caused pain for users. Notably, TensorFlow was forced check in generated code in this commit.
- This related to L25, in that it is making it easier to customize serialization code.
We will add a new API to the generated server code that signals for a method to be written in terms of ::grpc::ByteBuffer
. Marking a method as Raw
naturally means that it is asynchronous.
Selecting which methods are Raw
will be handled in the same manner as we currently allow for selection of Generic, Async, or Streamed methods. For example:
using SpecializedServer =
grpc::TestService::WithRawMethod_Foo<grpc::TestService::AsyncService>
This server would using protobuf to negotiate all methods except Foo, which would be handled with ByteBuffers. This allows the application to use whatever serialization mechanism they want for Foo.
Marking a method as Raw
is type unsafe since gRPC library cannot ensure that the user is serializing and deserializing with the same protocol. This feature is meant for "power users" who are willing to enforce the serialization invariant in their code.
Continuing with the example, if Foo were unary, then the server would interact with it like so:
// setup
SpecializedServer* server = BuildServer(...)
grpc::ServerCompletionQueue cq;
grpc::ServerContext srv_ctx;
// incoming
grpc::ByteBuffer recv_request_buffer;
grpc::GenericServerAsyncResponseWriter response_writer(&srv_ctx);
service->RequestEcho(&srv_ctx, &recv_request_buffer, &response_writer,
&cq, &cq, tag(1));
// outgoing
grpc::ByteBuffer send_response_buffer = ProcessRequestBB(recv_request_buffer);
response_writer.Finish(send_response_buffer, Status::OK, tag(2));
All other arities follow the same pattern.
The implementation will follow the same pattern as the generated code for async API, but will be written with ByteBuffer instead of proto objects. This implementation will cause the final
qualifier to be removed from the currently generated WithAsyncMethod_Foo
classes.
Implementation is in #15771