1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
use super::connection::Connection; use crate::transport::Endpoint; use std::{ collections::VecDeque, fmt, future::Future, pin::Pin, task::{Context, Poll}, }; use tower::discover::{Change, Discover}; pub(crate) struct ServiceList { list: VecDeque<Endpoint>, connecting: Option<Pin<Box<dyn Future<Output = Result<Connection, crate::Error>> + Send + 'static>>>, i: usize, } impl ServiceList { pub(crate) fn new(list: Vec<Endpoint>) -> Self { Self { list: list.into(), connecting: None, i: 0, } } } impl Discover for ServiceList { type Key = usize; type Service = Connection; type Error = crate::Error; fn poll_discover( mut self: Pin<&mut Self>, cx: &mut Context<'_>, ) -> Poll<Result<Change<Self::Key, Self::Service>, Self::Error>> { loop { if let Some(connecting) = &mut self.connecting { let svc = futures_core::ready!(Pin::new(connecting).poll(cx))?; self.connecting = None; let i = self.i; self.i += 1; let change = Ok(Change::Insert(i, svc)); return Poll::Ready(change); } if let Some(endpoint) = self.list.pop_front() { let mut http = hyper::client::connect::HttpConnector::new(); http.set_nodelay(endpoint.tcp_nodelay); http.set_keepalive(endpoint.tcp_keepalive); let fut = Connection::new(http, endpoint); self.connecting = Some(Box::pin(fut)); } else { return Poll::Pending; } } } } impl fmt::Debug for ServiceList { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("ServiceList") .field("list", &self.list) .finish() } }