Error while cloning the object wrapped under std::sync::Mutex

Hi,

I am storing objects of type "RequestHandler" in a Hashmap inside Router object. The Router object is designed to be a singleton and wrapped inside Mutex.

lazy_static! {
    static ref ROUTER: Arc<Mutex<Router>> = Arc::new(Mutex::new(Router::new()));
}

struct Router {
    routes: HashMap<String, RequestHandler<Box<dyn Fn(Request<Body>) -> RequestFuture + Send>>>,
...
...
}

impl Router {
    ...
    ...
    ...

    // fn get the RequestHandler clone from the hashmap
    fn get_route(&self, path: &str) -> Option<&RequestHandler<Box<dyn Fn(Request<Body>) -> RequestFuture + Send>>> {
        self.routes.get(path).clone()
    }
}

In one of my reconciling methods I am trying to get the clone of the RequestHandler object from the Hashmap like below.

async fn handle_request(req: Request<Body>) -> Result<Response<Body>, Infallible> {
    
    let path = req.uri().path().to_string();
    
    // get the route from the hashmap
    let route = {
        let routes = ROUTER.lock().unwrap();
        routes.get_route(&path).clone()
    };
...
...
...
  route.unwrap().call(req).await
}

But Compiler is throwing error like below

error[E0597]: `routes` does not live long enough
  --> src/http_server.rs:66:9
   |
64 |     let route = {
   |         ----- borrow later stored here
65 |         let routes = ROUTER.lock().unwrap();
66 |         routes.get_route(&path).clone()
   |         ^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
67 |     };
   |     - `routes` dropped here while still borrowed

Getting the impression Mutex will not allow Cloning of objects outside of it's lock scope. My requirement is to clone the object and drop the lock because later in the function I will be calling await which wouldn't allow locks while awaiting.

I am thinking of trying RWLock or tokio::Mutex (not sure if they will work) but it needs lot of fixes in my code, so looking for any help or suggestions before trying the afore mentioned options. Thanks!!

You are cloning the Option, which will just make another copy of the contained reference. Try Option::cloned instead: routes.get_route(&path).cloned()

Thanks @Jules-Bertholet , that worked

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.