这个 Future 的实现失败了什么?
What fails in this Future implementation?
虽然代码可以编译,但我不明白为什么直接使用 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)
}
已编辑:execute_requests
是一种简化:它需要访问 self
才能获取请求和其他内容。
每次轮询时,您都会创建一个新的 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)
}
虽然代码可以编译,但我不明白为什么直接使用 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)
}
已编辑:execute_requests
是一种简化:它需要访问 self
才能获取请求和其他内容。
每次轮询时,您都会创建一个新的 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)
}