| use std::task::{Context, Poll}; |
| use std::{future::Future, pin::Pin}; |
| use tower::util::ServiceExt; |
| use tower_service::Service; |
| |
| #[tokio::test(flavor = "current_thread")] |
| async fn service_driven_to_readiness() { |
| // This test ensures that `oneshot` will repeatedly call `poll_ready` until |
| // the service is ready. |
| let _t = super::support::trace_init(); |
| |
| struct PollMeTwice { |
| ready: bool, |
| } |
| impl Service<()> for PollMeTwice { |
| type Error = (); |
| type Response = (); |
| type Future = Pin< |
| Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send + Sync + 'static>, |
| >; |
| |
| fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), ()>> { |
| if self.ready { |
| Poll::Ready(Ok(())) |
| } else { |
| self.ready = true; |
| cx.waker().wake_by_ref(); |
| Poll::Pending |
| } |
| } |
| |
| fn call(&mut self, _: ()) -> Self::Future { |
| assert!(self.ready, "service not driven to readiness!"); |
| Box::pin(async { Ok(()) }) |
| } |
| } |
| |
| let svc = PollMeTwice { ready: false }; |
| svc.oneshot(()).await.unwrap(); |
| } |