future created by async block is not `Send` with tokio::sync::Mutex

293 Views Asked by At

I do a server update in rust. it create patches between 2 binaries files, and serves static files

I try to do

let mut update_state;
if let Some(state) = update_stream.next().await {
    if let Ok(state) = state {
        update_state = state
    } else if let Err(err) = state {
        reply = BuildOutput { error: "Update failed: ".to_string() + &err.to_string() }
    }
} else {
    reply = BuildOutput { error: "Unreacheable".to_string() }
}

let state = update_state.borrow();
let progress = state.histogram.progress();

let res = update_stream.try_for_each(|_state| future::ready(Ok(()))).await;

but get

let state = update_state.lock();
    |             ----- has type `tokio::sync::MutexGuard<'_, UpdateProgress>` which is not `Send`
...
273 |         let res = update_stream.try_for_each(|_state| future::ready(Ok(()))).await;
    |                                                                             ^^^^^^ await occurs here, with `state` maybe used later
...
305 |     }
    |     - `state` is later dropped here

update_state is

#[derive(Clone)]
pub struct SharedUpdateProgress {
    state: Arc<Mutex<UpdateProgress>>,
}

impl SharedUpdateProgress {
    pub fn new(target_revision: CleanName) -> Self {
        Self { state: Arc::new(Mutex::new(UpdateProgress::new(target_revision))) }
    }

    pub fn lock(&self) -> MutexGuard<'_, UpdateProgress> {
        self.state.lock().unwrap()
    }
}

type and Mutex/MutexGuard are from tokio::sync

UpdateProgress :

#[derive(Debug)]
pub struct UpdateProgress {
    /// Current update target revision
    pub target_revision: CleanName,

    /// Current update stage
    pub stage: UpdateStage,

    /// Number of files to download
    pub download_files: usize,
    /// Number of bytes to download
    pub download_bytes: u64,

    /// Number of files to install
    pub apply_files: usize,
    /// Number of bytes to apply
    pub apply_input_bytes: u64,
    /// Number of bytes to install
    pub apply_output_bytes: u64,

    /// Current package beeing applied
    pub downloading_package_idx: usize,
    /// Current operation beeing downloaded
    pub downloading_operation_idx: usize,

    /// Current package beeing applied
    pub applying_package_idx: usize,
    /// Current operation beeing applied
    pub applying_operation_idx: usize,

    /// Global update progression histogram
    pub histogram: Histogram<Progression>,

    /// Per step update progression
    pub steps: Vec<UpdateStepState>,
}

Before, I used RefCell but switch to std::sync::Arc and tokio::sync::Mutex to add Send trait but didn't fix my issue. So how to add Send trait or fix my issue ? Thanks

0

There are 0 best solutions below