Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to run multiple futures concurrently?

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

#[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.files outside 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())
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading