Lifetime issue: can't pass cloned Arc> into closure

⚓ Rust    📅 2025-08-15    👤 surdeus    👁️ 2      

surdeus

I want an Axum request handler to launch some worker threads and let them run, but have a way to get a read lock on a shared Arc<RwLock<City>> object.

I don't see why this doesn't work. City is behind an Arc, so the worker thread can be sure the main thread doesn't destroy/drop City. The main thread can only drop its own reference to it.

How can I work around this?

type Res<T> = Result<T, Box<dyn Error>>;

#[derive(Clone)]
pub struct AppState {
	city: Arc<RwLock<City>>,
}

struct Poi { coord: Point }

#[derive(Clone)]
pub struct City {}

impl City {
    pub fn get_pois_coords(&self) -> Res<&Vec<Poi>> {
        todo!()
    }
}

async fn start_calculation(Path(()): Path<()>, State(ast): State<AppState>) -> Result<(HeaderMap, Bytes), (StatusCode, String)> {
    let city: Arc<RwLock<City>> = ast.city.clone();
    let bgwork = move || -> Res<()> {
        let ct: std::sync::RwLockReadGuard<'_, City> = city.read()?;
                                                       ^^^^^^^^^^^^
         returning this value requires that `'1` must outlive `'static`
         note: closure implements `Fn`, so references to captured variables can't escape the closure
 
        let pois: &Vec<Poi> = ct.get_pois_coords()?;
        drop(pois);
        todo!()
    };  
    todo!()
}

2 posts - 2 participants

Read full topic

🏷️ Rust_feed