Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I share gRPC Stubs or Channels?

The gRPC C++ API for creating channels returns a shared_ptr. The generated function NewStub returns a unique_ptr. However I've seen reports of people having issues trying to create multiple instances of a stub type, sharing a channel. Their solution was to share the stub.

It is not clear from the documentation or API if a client is meant to create multiple stub instances sharing the channel or share a single stub. Please clarify the conceptual relationship between stubs, channels, and unique client connections.

Diving a little deeper: A server can serve more than one service and a client endpoint can use a single channel to connect corresponding stub types to each of those services. For that purpose, it is clear the different stub types share the single channel to talk to the server endpoint. Does gRPC expect only one client per channel for a given service or can I have multiple clients on the client endpoint talking to a single service? If allowed, how do I achieve multiple clients for a given service on a client endpoint? How does the server distinguish these as independent clients?

As an aside, This SO post indicates both Channels and Stubs are thread-safe. (The post is specifically for Java, but I'm assuming it carries over to C++).

like image 550
Ken Avatar asked Oct 30 '17 18:10

Ken


1 Answers

I think first we need to clarify the definitions for channel and stub, according to the official documents :

channel :

A gRPC channel provides a connection to a gRPC server on a specified host and port...

Conclude : A channel represents a single TCP connection.

stub :

On the client side, the client has a local object known as stub (for some languages, the preferred term is client) that implements the same methods as the service.

Conclude : A stub represents a single client.

From reading many other materials, I'm sure that a single channel(tcp connection) can be multiplexed, and now we get two options to achieve it:

  1. one channel <--> one stub
    one stub <--> multiple streams

  2. one channel <--> multiple stubs
    one stub <--> multiple streams

the only difference is that whether to share a channel among the stubs or not. My answer is: Yes, you can, for the reasons:

  1. your reports of people having issues example is written in ruby, but I can also find python examples standing on the opposite side. So the behavior may depends on language implementations.

  2. the synchronous cpp client examples use one stub object to issue a rpc, and it doesn't have any stream objects associated with, then the only way for multiplexing purpose is just share one single channel object among the stubs.

Combining the above two reasons, I conclude that: sharing a channel among the stubs is valid in C++.

Now, back to you questions:

Does gRPC expect only one client per channel for a given service or can I have multiple clients on the client endpoint talking to a single service?

Sure, you can have multiple clients talking to a single service.

If allowed, how do I achieve multiple clients for a given service on a client endpoint?

You can just have multiple stubs generated either from one single channel or from multiple channels, former is a better choice for connection overhead considerations.

How does the server distinguish these as independent clients?

This is due to http2, it can be multiplexed and has its own rules to achieve this, what grpc need to do is just follow thoes rules.

Hope this helps!

like image 148
pplorins Avatar answered Sep 22 '22 02:09

pplorins