0

虽然代码可以编译,但我不明白为什么await直接使用它会卡在第一个请求中。为什么我需要使用该方法execute_requests而不是在实现上调用它Future

// ...

async fn send(url: &str) {
    println!("Sending to URL {}", url);
    // Simulate the sending process
    sleep(Duration::from_millis(500)).await;
}

type Request = Pin<Box<dyn Future<Output = ()>>>;

struct Proxy;

impl Proxy {
    async fn execute_requests(&self) {
        let request_1 = async {
            send("url 1").await;
        };
        let request_2 = async {
            send("url 2").await;
        };

        let mut requests: Vec<Request> = vec![];
        requests.push(Box::pin(request_2));
        requests.push(Box::pin(request_1));

        while let Some(request) = requests.pop() {
            request.await;
        }
    }
}

impl Future for Proxy {
    type Output = ();

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let mut queue_process = Box::pin(self.execute_requests());
        queue_process.as_mut().poll(cx)
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let proxy = Proxy;
    // Executes both requests
    // Ok(proxy.execute_requests().await)
    // FIXME: Timeouts on the first request
    Ok(proxy.await)
}

锈游乐场

EDITED:execute_requests是一种简化:它需要访问以self获取请求和其他内容。

4

1 回答 1

1

每次轮询时,您都会创建一个新的execute_requests()未来并轮询一次。它永远不会进入下一次投票 - 下次你poll()被调用时,将创建一个新的未来并进行一次投票,依此类推。

相反,您应该将execute_requests()未来存储在 中Proxy,并轮询相同的未来:

struct Proxy(Pin<Box<dyn Future<Output = ()>>>);

impl Proxy {
    fn new() -> Self {
        Self(Box::pin(Self::execute_requests()))
    }
    
    async fn execute_requests() {
        let request_1 = async {
            send("url 1").await;
        };
        let request_2 = async {
            send("url 2").await;
        };

        let mut requests: Vec<Request> = vec![];
        requests.push(Box::pin(request_2));
        requests.push(Box::pin(request_1));

        while let Some(request) = requests.pop() {
            request.await;
        }
    }
}

impl Future for Proxy {
    type Output = ();

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        self.0.as_mut().poll(cx)
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let proxy = Proxy::new();
    // Executes both requests
    // Ok(proxy.execute_requests().await)
    // FIXME: Timeouts on the first request
    Ok(proxy.await)
}

游乐场

于 2022-02-18T10:59:21.220 回答