hyperium / tonic

A native gRPC client & server implementation with async/await support.
https://docs.rs/tonic
MIT License
9.77k stars 997 forks source link

Ability to pass customized connector for channel with multiple endpoints #1476

Open wenym1 opened 1 year ago

wenym1 commented 1 year ago

Feature Request

Crates

tonic

https://github.com/hyperium/tonic/tree/master/tonic/src/transport/channel

Motivation

For channel with a single endpoint, we can create the channel with customized connector by calling Endpoint::connect_with_connector.

However, we are not able to pass a customized connector for channel with multiple endpoints created from balance_xxx methods. Reasons are as followed.

Currently we have several public methods to create a balanced channel: balance_list, balance_channel and balance_channel_with_executor, where balance_list is based on balance_channel and balance_channel is based on balance_channel_with_executor. The balance_channel_with_executor is based on the balance method. The balance method accepts a parameter that implements Discover<Service = Connection>, which provides the ability to pass some customized logic. However, the balance method is private to crate, and cannot be used externally. When balance_channel_with_executor calls balance, it pass the DynamicServiceStream as the parameter that implements Discover<Service = Connection>. But in the poll_next of DynamicServiceStream, it creates all the connection from hyper::client::connect::HttpConnector, which is hard-coded and cannot be customized.

Proposal

Make the following changes:

  1. Turn DynamicServiceStream from pub(crate) to pub. Meanwhile, add new generic parameter M: MakeConnection<Uri> + From<Endpoint> to DynamicServiceStream. Implements Into<hyper::client::connect::HttpConnector> for Endpoint so that hyper::client::connect::HttpConnector satisfies the trait bound of M.
  2. Turn the balance method from pub(crate) to pub.

Alternatives

wenym1 commented 1 year ago

I am willing to make such refactor if needed.