I’m running a http server using actix_web which has an endpoint that receives some files, which I need to process. For the async runtime, I’m using tokio. The thing is, I want to process the files concurrently, but there are some issues.
The first issue is that the body doesn’t live long enough, since it’s not ' static typed.
The second issue is that I need to pass some variables to the function that actually process the file, but I’m getting the use of moved value error.
This is the code:
#[post("/images")]
async fn process_images(
body: Json<ProcessFilesBody>,
aws: Data<AWSService>,
) -> Result<impl Responder, Error> {
println!("PROCESSING {:?} FILES", body.0.files.len());
let mut futures = Vec::new();
for file in &body.0.files {
let handle = spawn(async move {
process_file(aws.clone(), &file).await;
});
futures.push(handle);
}
for handle in futures {
handle.await.unwrap();
}
Ok(HttpResponse::Ok())
}
I’ve tried wraping the aws variable in an Arc but didn’t work and I have no clue how to fix the lifetime of the files
>Solution :
Clone
body.0.filesoutside the loop to resolve the lifetime issue.
Use
aws.get_ref().clone()to clone the inner AWSService.
#[post("/images")]
async fn process_images(
body: Json<ProcessFilesBody>,
aws: Data<AWSService>,
) -> Result<impl Responder, Error> {
println!("PROCESSING {:?} FILES", body.0.files.len());
let files = body.into_inner().files.clone(); // Clone files here
let aws_service = aws.get_ref().clone(); // Clone AWSService here
let mut futures = Vec::new();
for file in files {
let aws_clone = aws_service.clone(); // Clone for each async block
let handle = tokio::spawn(async move {
process_file(aws_clone, file).await;
});
futures.push(handle);
}
for handle in futures {
handle.await.unwrap();
}
Ok(HttpResponse::Ok())
}