tonic/transport/channel/
mod.rs1mod endpoint;
28pub(crate) mod service;
29#[cfg(feature = "_tls-any")]
30mod tls;
31mod uds_connector;
32
33pub use self::service::Change;
34pub use endpoint::Endpoint;
35#[cfg(feature = "_tls-any")]
36pub use tls::ClientTlsConfig;
37
38use self::service::{Connection, DynamicServiceStream, Executor, SharedExec};
39use crate::body::Body;
40use bytes::Bytes;
41use http::{
42 Request, Response,
43 uri::{InvalidUri, Uri},
44};
45use std::{
46 fmt,
47 future::Future,
48 hash::Hash,
49 pin::Pin,
50 task::{Context, Poll},
51};
52use tokio::sync::mpsc::{Sender, channel};
53
54use hyper::rt;
55use tower::balance::p2c::Balance;
56use tower::{
57 Service,
58 buffer::{Buffer, future::ResponseFuture as BufferResponseFuture},
59 discover::Discover,
60 util::BoxService,
61};
62
63type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
64
65const DEFAULT_BUFFER_SIZE: usize = 1024;
66
67#[derive(Clone)]
91pub struct Channel {
92 svc: Buffer<Request<Body>, BoxFuture<'static, Result<Response<Body>, crate::BoxError>>>,
93}
94
95pub struct ResponseFuture {
99 inner: BufferResponseFuture<BoxFuture<'static, Result<Response<Body>, crate::BoxError>>>,
100}
101
102impl Channel {
103 pub fn builder(uri: Uri) -> Endpoint {
105 Endpoint::from(uri)
106 }
107
108 pub fn from_static(s: &'static str) -> Endpoint {
115 let uri = Uri::from_static(s);
116 Self::builder(uri)
117 }
118
119 pub fn from_shared(s: impl Into<Bytes>) -> Result<Endpoint, InvalidUri> {
126 let uri = Uri::from_maybe_shared(s.into())?;
127 Ok(Self::builder(uri))
128 }
129
130 pub fn balance_list(list: impl Iterator<Item = Endpoint>) -> Self {
135 let (channel, tx) = Self::balance_channel(DEFAULT_BUFFER_SIZE);
136 list.for_each(|endpoint| {
137 tx.try_send(Change::Insert(endpoint.uri.clone(), endpoint))
138 .unwrap();
139 });
140
141 channel
142 }
143
144 pub fn balance_channel<K>(capacity: usize) -> (Self, Sender<Change<K, Endpoint>>)
148 where
149 K: Hash + Eq + Send + Clone + 'static,
150 {
151 Self::balance_channel_with_executor(capacity, SharedExec::tokio())
152 }
153
154 pub fn balance_channel_with_executor<K, E>(
160 capacity: usize,
161 executor: E,
162 ) -> (Self, Sender<Change<K, Endpoint>>)
163 where
164 K: Hash + Eq + Send + Clone + 'static,
165 E: Executor<Pin<Box<dyn Future<Output = ()> + Send>>> + Send + Sync + 'static,
166 {
167 let (tx, rx) = channel(capacity);
168 let list = DynamicServiceStream::new(rx);
169 (Self::balance(list, DEFAULT_BUFFER_SIZE, executor), tx)
170 }
171
172 pub fn new<C>(connector: C, endpoint: Endpoint) -> Self
176 where
177 C: Service<Uri> + Send + 'static,
178 C::Error: Into<crate::BoxError> + Send,
179 C::Future: Send,
180 C::Response: rt::Read + rt::Write + Unpin + Send + 'static,
181 {
182 let buffer_size = endpoint.buffer_size.unwrap_or(DEFAULT_BUFFER_SIZE);
183 let executor = endpoint.executor.clone();
184
185 let svc = Connection::lazy(connector, endpoint);
186 let (svc, worker) = Buffer::pair(svc, buffer_size);
187
188 executor.execute(worker);
189
190 Channel { svc }
191 }
192
193 pub async fn connect<C>(connector: C, endpoint: Endpoint) -> Result<Self, super::Error>
197 where
198 C: Service<Uri> + Send + 'static,
199 C::Error: Into<crate::BoxError> + Send,
200 C::Future: Unpin + Send,
201 C::Response: rt::Read + rt::Write + Unpin + Send + 'static,
202 {
203 let buffer_size = endpoint.buffer_size.unwrap_or(DEFAULT_BUFFER_SIZE);
204 let executor = endpoint.executor.clone();
205
206 let svc = Connection::connect(connector, endpoint)
207 .await
208 .map_err(super::Error::from_source)?;
209 let (svc, worker) = Buffer::pair(svc, buffer_size);
210 executor.execute(worker);
211
212 Ok(Channel { svc })
213 }
214
215 pub(crate) fn balance<D, E>(discover: D, buffer_size: usize, executor: E) -> Self
216 where
217 D: Discover<Service = Connection> + Unpin + Send + 'static,
218 D::Error: Into<crate::BoxError>,
219 D::Key: Hash + Send + Clone,
220 E: Executor<BoxFuture<'static, ()>> + Send + Sync + 'static,
221 {
222 let svc = Balance::new(discover);
223
224 let svc = BoxService::new(svc);
225 let (svc, worker) = Buffer::pair(svc, buffer_size);
226 executor.execute(Box::pin(worker));
227
228 Channel { svc }
229 }
230}
231
232impl Service<http::Request<Body>> for Channel {
233 type Response = http::Response<Body>;
234 type Error = super::Error;
235 type Future = ResponseFuture;
236
237 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
238 Service::poll_ready(&mut self.svc, cx).map_err(super::Error::from_source)
239 }
240
241 fn call(&mut self, request: http::Request<Body>) -> Self::Future {
242 let inner = Service::call(&mut self.svc, request);
243
244 ResponseFuture { inner }
245 }
246}
247
248impl Future for ResponseFuture {
249 type Output = Result<Response<Body>, super::Error>;
250
251 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
252 Pin::new(&mut self.inner)
253 .poll(cx)
254 .map_err(super::Error::from_source)
255 }
256}
257
258impl fmt::Debug for Channel {
259 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
260 f.debug_struct("Channel").finish()
261 }
262}
263
264impl fmt::Debug for ResponseFuture {
265 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
266 f.debug_struct("ResponseFuture").finish()
267 }
268}