gpt4 book ai didi

asynchronous - 在 actix-web 中生成从多部分读取数据

转载 作者:行者123 更新时间:2023-12-03 11:43:55 26 4
gpt4 key购买 nike

我试过 example of actix-multipartactix-web v3.3.2actix-multipart v0.3.0 .
举一个最小的例子,

use actix_multipart::Multipart;
use actix_web::{post, web, App, HttpResponse, HttpServer};
use futures::{StreamExt, TryStreamExt};

#[post("/")]
async fn save_file(mut payload: Multipart) -> HttpResponse {
while let Ok(Some(mut field)) = payload.try_next().await {
let content_type = field.content_disposition().unwrap();
let filename = content_type.get_filename().unwrap();
println!("filename = {}", filename);

while let Some(chunk) = field.next().await {
let data = chunk.unwrap();
println!("Read a chunk.");
}
println!("Done");
}
HttpResponse::Ok().finish()
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new().service(save_file))
.bind("0.0.0.0:8080")?
.run()
.await
}
这很好用,但我想异步处理表单数据。所以我尝试了:
use actix_multipart::Multipart;
use actix_web::{post, web, App, HttpResponse, HttpServer};
use futures::{StreamExt, TryStreamExt};

#[post("/")]
async fn save_file(mut payload: Multipart) -> HttpResponse {
actix_web::rt::spawn(async move {
while let Ok(Some(mut field)) = payload.try_next().await {
let content_type = field.content_disposition().unwrap();
let filename = content_type.get_filename().unwrap();
println!("filename = {}", filename);

while let Some(chunk) = field.next().await {
let data = chunk.unwrap();
println!("Read a chunk.");
}
println!("Done");
}
});
HttpResponse::Ok().finish()
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| App::new().service(save_file))
.bind("0.0.0.0:8080")?
.run()
.await
}
(已添加 actix_web::rt::spawnsave_file。)
但这不起作用——消息 "Done"从未打印过。数量 "Read a chunk"第二种情况显示的比第一种情况少,所以我猜 field.next().await在完成读取所有数据之前由于某种原因无法终止。
我对异步编程了解不多,所以不知道为什么 field.next()不适用于 actix_web::rt::spawn .
我的问题是:为什么会这样,我该如何处理 actix_web::rt::spawn ?

最佳答案

当您调用此电话时:

actix_web::rt::spawn(async move {
// do things...
});
spawn返回 JoinHandle用于轮询任务。当您放下该句柄(不将其绑定(bind)到任何东西)时,该任务将“分离”,即它在后台运行。 actix文档在这里不是特别有用,但是 actix使用 tokio引擎盖下的运行时。一个关键问题是在 tokio , 生成的任务不能保证完成 .执行者需要以某种方式知道它应该在那个 future 执行工作。在您的第二个示例中,生成的任务永远不会是 .await ed,它也不通过 channel 与任何其他任务进行通信。
最有可能的是,生成的任务永远不会被轮询,也不会取得任何进展。为了确保它完成,您可以 .await JoinHandle (这将插入任务完成)或 .await其他一些 Future这取决于衍生任务中的工作(通常通过使用 channel )。

至于您的更一般的目标,工作已经在异步执行!最有可能, actix正在大致执行您在第二个示例中尝试执行的操作:收到请求后,它会生成一个任务来处理请求并反复轮询它(以及其他事件请求),直到它完成,然后发送响应。

关于asynchronous - 在 actix-web 中生成从多部分读取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66169240/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com