Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best approach to stream multiple types with GRPC

I have a server that passes messages to a client. The messages are of different types and the server has a generic handleMessage and passMessage method for the clients.

Now I intend to adapt this and use GRPC for it. I know I could expose all methods of the server by defining services in my .proto file. But is there also a way to:

  • Stream
  • heterogenous types
  • with one RPC call
  • using GRPC

There is oneof which allows me to set a message that has only one of the properties set. I could have a MessageContainer that is oneof and all my message types are included in this container. Now the container only has one of the types and I would only need to write one

service {
   rpc messageHandler(ClientInfo)  returns (stream MessageContainer)
}

This way, the server could stream multiple types to the client through one unique interface. Does this make sense? Or is it better to have all methods exposed individually?

UPDATE

I found this thread which argues oneof would be the way to go. I'd like that obviously as it avoids me having to create potentially dozens of services and stubs. It would also help to make sure it's a FIFO setup instead of multiplexing several streams and not being sure which message came first. But it feels dirty for some reason.

like image 504
pascalwhoop Avatar asked Feb 20 '18 16:02

pascalwhoop


People also ask

Can gRPC handle multiple clients?

Multiple gRPC clients can be created from a channel, including different types of clients. A channel and clients created from the channel can safely be used by multiple threads. Clients created from the channel can make multiple simultaneous calls.

Is gRPC good for streaming?

gRPC supports streaming semantics, where either the client or the server (or both) send a stream of messages on a single RPC call. The most general case is Bidirectional Streaming where a single gRPC call establishes a stream in which both the client and the server can send a stream of messages to each other.

Can a gRPC server have multiple services?

All the gRPC implementations support multiple services in the same process and port. All implementations also support using different ports for each the service, if you have a reason to prefer that.

What is bidirectional streaming in gRPC?

In a bidirectional streaming RPC, the call is initiated by the client invoking the method and the server receiving the client metadata, method name, and deadline. The server can choose to send back its initial metadata or wait for the client to start streaming messages.


1 Answers

Yes, this makes sense (and what you are calling MessageContainer is best understood as a sum type).

... but it is still better to define different methods when you can ("better" here means "more idiomatic, more readable by future maintainers of your system, and better able to be changed in the future when method semantics need to change").

The question of whether to express your service as a single RPC method returning a sum type or as multiple RPC methods comes down to whether or not the particular addend type that will be used can be known at RPC invocation time. Is it the case that when you set request.my_type_determining_field to 5 that the stream transmitted by the server always consists of MessageContainer messages that have their oneof set to a MyFifthKindOfParticularMessage instance? If so then you should probably just write a separate RPC method that returns a stream of MyFifthKindOfParticularMessage messages. If, however, it is the case that at RPC invocation time you don't know with certainty what the used addend types of the messages transmitted from the server will be (and "messages with different addend types in the same stream" is a sub-use-case of this), then I don't think it's possible for your service to be factored into different RPCs and the right thing for you to do is have one RPC method that returns a stream of a sum type.

like image 194
Nathaniel Manista At Google Avatar answered Sep 28 '22 13:09

Nathaniel Manista At Google