I have a future and it needs to poll two different futures in its fn poll, I couldn't work out why it the futures are executed in a strange way
impl<F, E> Future for ResponseFuture<F>
where
F: Future<Output = Result<String, E>>,
{
type Output = F::Output;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
// First future
// Get back the HTTP response
println!("polling, before 1st future");
let res = ready!(this.inner.poll(cx)?);
// Second future
// save the url returned by the `res`
println!("polling, before 2nd future");
let url: DbUrl = ready!(std::pin::pin!(save("a url from the resp")).poll(cx)).unwrap();
println!("all done");
Poll::Ready(Ok(res))
}
}
// source: https://docs.rs/sea-orm/2.0.0-rc.27/sea_orm/entity/trait.ActiveModelTrait.html#method.save
fn save(_url: &str) -> Pin<Box<dyn Future<Output = Result<DbUrl, DbErr>> + Send>>
where
{
Box::pin(async { Ok(DbUrl) })
}
I tried to reduce it to a playground example but I just couldn't reproduce the problem, on the playground example, it runs without problem
polling, before 1st future
polling, before 2nd future
all done
However, with my actual code, the behaviour is strange
// possible outcome 1
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 2nd future << stuck here
// possible outcome 2
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 2nd future
polling, before 1st future
thread 'tokio-runtime-worker' (265203) panicked at /home/chung/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hyper-util-0.1.19/src/client/legacy/client.rs:246:57:
`async fn` resumed after completion
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrac
// possible outcome 3
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 2nd future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 2nd future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 2nd future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 2nd future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 2nd future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 1st future
polling, before 2nd future <<< stuck
My actual code
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
println!("polling, before 1st future");
let res = ready!(this.inner.poll(cx)?);
let cur_url = url::ActiveModel {
..Default::default()
};
println!("polling, before 2nd future");
let cur_url = ready!(pin!(cur_url.save(this.db)).poll(cx));
println!("all done");
Poll::Ready(Ok(res))
}