In order to close a client, users can either hold onto the underlying channels themselves, or, given a DGraphClient, use reflection to read the clients field, iterate over those clients (Stubs), and call stub.getChannel().shutdown() on each stub. It might be handy to have a close() method that does that, so users don’t have to use reflection hacks.
There is one awkward bit that makes this a bit tricky. the clients field is of type DgraphGrpc.DgraphBlockingStub, which has a public getChannel() method. However, the return type of getChannel() is class Channel and not ManagedChannel. Channel does not have a shutdown() method associated with it.
We have two options:
Force the Channel type returned to ManagedChannel and then call shutdown() on it. This will work for existing clients, but its a bit hacky and inflexible.
We can make this abstraction cleaner, by using our own type for the clients field (maybe something like DgraphGrpcClientPool, which wraps around a list of DgraphGrpc.DgraphBlockingStub objects. This would mean a breaking change, however.
Let me think a little bit more about this and implement something.
It might be better for the consumer of the client api to manage and close the channels themselves. This keeps the client code minimal. In any case the DgraphGrpc.DgraphStub#getChannel() method has a Channel return type. The Channel interface does not include the shutdown() method, so we need to perform a forced typecast anyway.