Returns a reference to a captured variable which escapes the closure body

The following code compiles.

pub async fn run(port:u16, circle: Arc<ConsistentHashCircle>) -> Result<(), hyper::error::Error> {

    let make_service = make_service_fn(move |_| {
        let cloned_circle = circle.clone();
        async move {
            
            Ok::<_, hyper::Error>(service_fn( move |mut req| async {
                let addr = get_server_addr(&mut req).await?;

                let client = get_client(&addr);
                client.request(req).await
            }))
        }
    });

    let addr = SocketAddr::from(([0, 0, 0, 0], port));
    let server = Server::bind(&addr).serve(make_service);
    server.await?;

    // ...
}


async fn get_server_addr(req: &mut Request<Body>) -> Result<String, hyper::Error> {

    // ...
}

I want to pass circle: Arc<ConsistentHashCircle> into get_server_addr method.

pub async fn run(port:u16, circle: Arc<ConsistentHashCircle>) -> Result<(), hyper::error::Error> {

    let make_service = make_service_fn(move |_| {
        let cloned_circle = circle.clone();
        async move {
            
            Ok::<_, hyper::Error>(service_fn( move |mut req| async {
                let addr = get_server_addr(&mut req, cloned_circle.clone()).await?;

                let client = get_client(&addr);
                client.request(req).await
            }))
        }
    });

    let addr = SocketAddr::from(([0, 0, 0, 0], port));
    let server = Server::bind(&addr).serve(make_service);
    server.await?;

    // ...
}


async fn get_server_addr(req: &mut Request<Body>, circle: Arc<ConsistentHashCircle>) -> Result<String, hyper::Error> {

    // ...
}

It ends with an error,

returns a reference to a captured variable which escapes the closure body

How can I pass circle into get_server_addr ?

Thank you

Your clones are in the wrong positions. Remember that async closures are really ordinary closures that return async blocks, and if you need to clone something, that clone has to go in the closure, not the async block.

let make_service = make_service_fn(move |_| {
    let circle = circle.clone();
    async move {
        Ok::<_, std::convert::Infallible>(service_fn(move |mut req| {
            let circle = circle.clone();
            async move {
                let addr = get_server_addr(&mut req, circle).await?;
    
                let client = get_client(&addr);
                client.request(req).await
            }
        }))
    }
});
1 Like

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.