1 use super::{AddOrigin, Reconnect, SharedExec, UserAgent}; 2 use crate::{ 3 body::Body, 4 transport::{channel::BoxFuture, service::GrpcTimeout, Endpoint}, 5 }; 6 use http::{Request, Response, Uri}; 7 use hyper::rt; 8 use hyper::{client::conn::http2::Builder, rt::Executor}; 9 use hyper_util::rt::TokioTimer; 10 use std::{ 11 fmt, 12 task::{Context, Poll}, 13 }; 14 use tower::load::Load; 15 use tower::{ 16 layer::Layer, 17 limit::{concurrency::ConcurrencyLimitLayer, rate::RateLimitLayer}, 18 util::BoxService, 19 ServiceBuilder, ServiceExt, 20 }; 21 use tower_service::Service; 22 23 pub(crate) struct Connection { 24 inner: BoxService<Request<Body>, Response<Body>, crate::BoxError>, 25 } 26 27 impl Connection { new<C>(connector: C, endpoint: Endpoint, is_lazy: bool) -> Self where C: Service<Uri> + Send + 'static, C::Error: Into<crate::BoxError> + Send, C::Future: Send, C::Response: rt::Read + rt::Write + Unpin + Send + 'static,28 fn new<C>(connector: C, endpoint: Endpoint, is_lazy: bool) -> Self 29 where 30 C: Service<Uri> + Send + 'static, 31 C::Error: Into<crate::BoxError> + Send, 32 C::Future: Send, 33 C::Response: rt::Read + rt::Write + Unpin + Send + 'static, 34 { 35 let mut settings: Builder<SharedExec> = Builder::new(endpoint.executor.clone()) 36 .initial_stream_window_size(endpoint.init_stream_window_size) 37 .initial_connection_window_size(endpoint.init_connection_window_size) 38 .keep_alive_interval(endpoint.http2_keep_alive_interval) 39 .timer(TokioTimer::new()) 40 .clone(); 41 42 if let Some(val) = endpoint.http2_keep_alive_timeout { 43 settings.keep_alive_timeout(val); 44 } 45 46 if let Some(val) = endpoint.http2_keep_alive_while_idle { 47 settings.keep_alive_while_idle(val); 48 } 49 50 if let Some(val) = endpoint.http2_adaptive_window { 51 settings.adaptive_window(val); 52 } 53 54 if let Some(val) = endpoint.http2_max_header_list_size { 55 settings.max_header_list_size(val); 56 } 57 58 let stack = ServiceBuilder::new() 59 .layer_fn(|s| { 60 let origin = endpoint.origin.as_ref().unwrap_or(&endpoint.uri).clone(); 61 62 AddOrigin::new(s, origin) 63 }) 64 .layer_fn(|s| UserAgent::new(s, endpoint.user_agent.clone())) 65 .layer_fn(|s| GrpcTimeout::new(s, endpoint.timeout)) 66 .option_layer(endpoint.concurrency_limit.map(ConcurrencyLimitLayer::new)) 67 .option_layer(endpoint.rate_limit.map(|(l, d)| RateLimitLayer::new(l, d))) 68 .into_inner(); 69 70 let make_service = 71 MakeSendRequestService::new(connector, endpoint.executor.clone(), settings); 72 73 let conn = Reconnect::new(make_service, endpoint.uri.clone(), is_lazy); 74 75 Self { 76 inner: BoxService::new(stack.layer(conn)), 77 } 78 } 79 connect<C>( connector: C, endpoint: Endpoint, ) -> Result<Self, crate::BoxError> where C: Service<Uri> + Send + 'static, C::Error: Into<crate::BoxError> + Send, C::Future: Unpin + Send, C::Response: rt::Read + rt::Write + Unpin + Send + 'static,80 pub(crate) async fn connect<C>( 81 connector: C, 82 endpoint: Endpoint, 83 ) -> Result<Self, crate::BoxError> 84 where 85 C: Service<Uri> + Send + 'static, 86 C::Error: Into<crate::BoxError> + Send, 87 C::Future: Unpin + Send, 88 C::Response: rt::Read + rt::Write + Unpin + Send + 'static, 89 { 90 Self::new(connector, endpoint, false).ready_oneshot().await 91 } 92 lazy<C>(connector: C, endpoint: Endpoint) -> Self where C: Service<Uri> + Send + 'static, C::Error: Into<crate::BoxError> + Send, C::Future: Send, C::Response: rt::Read + rt::Write + Unpin + Send + 'static,93 pub(crate) fn lazy<C>(connector: C, endpoint: Endpoint) -> Self 94 where 95 C: Service<Uri> + Send + 'static, 96 C::Error: Into<crate::BoxError> + Send, 97 C::Future: Send, 98 C::Response: rt::Read + rt::Write + Unpin + Send + 'static, 99 { 100 Self::new(connector, endpoint, true) 101 } 102 } 103 104 impl Service<Request<Body>> for Connection { 105 type Response = Response<Body>; 106 type Error = crate::BoxError; 107 type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>; 108 poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>109 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { 110 Service::poll_ready(&mut self.inner, cx).map_err(Into::into) 111 } 112 call(&mut self, req: Request<Body>) -> Self::Future113 fn call(&mut self, req: Request<Body>) -> Self::Future { 114 self.inner.call(req) 115 } 116 } 117 118 impl Load for Connection { 119 type Metric = usize; 120 load(&self) -> Self::Metric121 fn load(&self) -> Self::Metric { 122 0 123 } 124 } 125 126 impl fmt::Debug for Connection { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result127 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 128 f.debug_struct("Connection").finish() 129 } 130 } 131 132 struct SendRequest { 133 inner: hyper::client::conn::http2::SendRequest<Body>, 134 } 135 136 impl From<hyper::client::conn::http2::SendRequest<Body>> for SendRequest { from(inner: hyper::client::conn::http2::SendRequest<Body>) -> Self137 fn from(inner: hyper::client::conn::http2::SendRequest<Body>) -> Self { 138 Self { inner } 139 } 140 } 141 142 impl tower::Service<Request<Body>> for SendRequest { 143 type Response = Response<Body>; 144 type Error = crate::BoxError; 145 type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>; 146 poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>147 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { 148 self.inner.poll_ready(cx).map_err(Into::into) 149 } 150 call(&mut self, req: Request<Body>) -> Self::Future151 fn call(&mut self, req: Request<Body>) -> Self::Future { 152 let fut = self.inner.send_request(req); 153 154 Box::pin(async move { fut.await.map_err(Into::into).map(|res| res.map(Body::new)) }) 155 } 156 } 157 158 struct MakeSendRequestService<C> { 159 connector: C, 160 executor: SharedExec, 161 settings: Builder<SharedExec>, 162 } 163 164 impl<C> MakeSendRequestService<C> { new(connector: C, executor: SharedExec, settings: Builder<SharedExec>) -> Self165 fn new(connector: C, executor: SharedExec, settings: Builder<SharedExec>) -> Self { 166 Self { 167 connector, 168 executor, 169 settings, 170 } 171 } 172 } 173 174 impl<C> tower::Service<Uri> for MakeSendRequestService<C> 175 where 176 C: Service<Uri> + Send + 'static, 177 C::Error: Into<crate::BoxError> + Send, 178 C::Future: Send, 179 C::Response: rt::Read + rt::Write + Unpin + Send, 180 { 181 type Response = SendRequest; 182 type Error = crate::BoxError; 183 type Future = BoxFuture<'static, Result<Self::Response, Self::Error>>; 184 poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>185 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { 186 self.connector.poll_ready(cx).map_err(Into::into) 187 } 188 call(&mut self, req: Uri) -> Self::Future189 fn call(&mut self, req: Uri) -> Self::Future { 190 let fut = self.connector.call(req); 191 let builder = self.settings.clone(); 192 let executor = self.executor.clone(); 193 194 Box::pin(async move { 195 let io = fut.await.map_err(Into::into)?; 196 let (send_request, conn) = builder.handshake(io).await?; 197 198 Executor::<BoxFuture<'static, ()>>::execute( 199 &executor, 200 Box::pin(async move { 201 if let Err(e) = conn.await { 202 tracing::debug!("connection task error: {:?}", e); 203 } 204 }) as _, 205 ); 206 207 Ok(SendRequest::from(send_request)) 208 }) 209 } 210 } 211