Spawn multiple threads to execute async requests to a server

#[tokio::main()]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    static APP_USER_AGENT: &str = concat!(
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246"
    );    
    let client = Client::builder()
        .user_agent(APP_USER_AGENT)
        .cookie_store(true)
        .build()?;    
    let token: String = fs::read_to_string("token.txt")?.parse()?;
    let rt = Runtime::new().unwrap();
    login(&client,token).await?; // authentication call to endpoint
    loop{
        let new_items = get_orders(&client).await?; //  call to get orders from the server // this is where ther error shows up
        if new_items.pagination.qty_total > 0 {
            for order in new_items.new_items {  // I'm trying to process the orders concurrently with tokio(since it supports async functions in threads)
                rt.block_on(async move {
                    tokio::spawn(async move { process_order(&client, &order).await; });
                });
            }             
        }
    }
}

I can not seem to find a way to fix the error :

borrow of moved value: client

value borrowed here after moverustc(E0382)

main.rs(17, 9): move occurs because client has type reqwest::Client, which does not implement the Copy trait

main.rs(26, 36): value borrowed here after move

main.rs(29, 40): value moved here, in previous iteration of loop

i'm quite new in rust and any help would be greatly appreciated

Typically you shouldn’t be creating another runtime inside of a #[tokio::main] main function, or execute block_on in async code. Just use tokio::spawn directly. Also, calling rt.block_on in a loop means that nothing would happen concurrently.

Regarding the error in question, for shared access to client in multiple spawned tasks, put the Client into an Arc and pass a clone of that Arc to each task. Or even better just clone the Client if the struct supports it. (I’m not sure what library you use here.)

Edit: Assuming this is reqwest, you should clone the Client itself, not use an Arc.

In the for loop you are moving the client, due to the closure capturing it. You should use a thread-safe pointer such as Arc so that each thread can have a reference to the client.

This was really helpful, Thanks

I am using reqwest::Client which already uses an Arc internally according to their docs

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.