| #![cfg(feature = "steer")] |
| #[path = "../support.rs"] |
| mod support; |
| |
| use futures_util::future::{ready, Ready}; |
| use std::task::{Context, Poll}; |
| use tower::steer::Steer; |
| use tower_service::Service; |
| |
| type StdError = Box<dyn std::error::Error + Send + Sync + 'static>; |
| |
| struct MyService(u8, bool); |
| |
| impl Service<String> for MyService { |
| type Response = u8; |
| type Error = StdError; |
| type Future = Ready<Result<u8, Self::Error>>; |
| |
| fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { |
| if !self.1 { |
| Poll::Pending |
| } else { |
| Poll::Ready(Ok(())) |
| } |
| } |
| |
| fn call(&mut self, _req: String) -> Self::Future { |
| ready(Ok(self.0)) |
| } |
| } |
| |
| #[tokio::test(flavor = "current_thread")] |
| async fn pick_correctly() { |
| let _t = support::trace_init(); |
| let srvs = vec![MyService(42, true), MyService(57, true)]; |
| let mut st = Steer::new(srvs, |_: &_, _: &[_]| 1); |
| |
| futures_util::future::poll_fn(|cx| st.poll_ready(cx)) |
| .await |
| .unwrap(); |
| let r = st.call(String::from("foo")).await.unwrap(); |
| assert_eq!(r, 57); |
| } |
| |
| #[tokio::test(flavor = "current_thread")] |
| async fn pending_all_ready() { |
| let _t = support::trace_init(); |
| |
| let srvs = vec![MyService(42, true), MyService(57, false)]; |
| let mut st = Steer::new(srvs, |_: &_, _: &[_]| 0); |
| |
| let p = futures_util::poll!(futures_util::future::poll_fn(|cx| st.poll_ready(cx))); |
| match p { |
| Poll::Pending => (), |
| _ => panic!( |
| "Steer should not return poll_ready if at least one component service is not ready" |
| ), |
| } |
| } |