'tokio spawn_blocking error when 3rd party code is not thread safe

I am trying to create a test container in [tokio::test],

#[cfg(test)]
mod tests {
    use std::sync::{Arc, Mutex};
    use testcontainers::*;
    use anyhow::Result;
    use tokio::task;
    use testcontainers::images::postgres::Postgres;

    #[tokio::test]
    async fn test_pg_store() -> Result<()> {
        let docker = Arc::new(Mutex::new(clients::Cli::default()));
        let _node = task::spawn_blocking(move || {
            let pg = Postgres::default();
            let c = docker.lock().unwrap().run(pg);
            Arc::new(Mutex::new(c))
        }).await?;

        Ok(())
    }
}

docker.run(pg); is likely to take seconds so I need to use spawn_blocking. However, got the error

error[E0277]: `(dyn core::container::Docker + 'static)` cannot be sent between threads safely
   --> access/src/store/postgres.rs:40:42
    |
40  |           let _node = task::spawn_blocking(move || {
    |  _____________________--------------------_^
    | |                     |
    | |                     required by a bound introduced by this call
41  | |             let pg = Postgres::default();
42  | |             let c = docker.lock().unwrap().run(pg);
43  | |             Arc::new(Mutex::new(c))
44  | |         }).await?;
    | |_________^ `(dyn core::container::Docker + 'static)` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `(dyn core::container::Docker + 'static)`
    = note: required because of the requirements on the impl of `Send` for `Unique<(dyn core::container::Docker + 'static)>`
    = note: required because it appears within the type `Box<(dyn core::container::Docker + 'static)>`
    = note: required because it appears within the type `Container<'_, Postgres>`
    = note: required because of the requirements on the impl of `Sync` for `std::sync::Mutex<Container<'_, Postgres>>`
    = note: 1 redundant requirement hidden
    = note: required because of the requirements on the impl of `Send` for `std::sync::Arc<std::sync::Mutex<Container<'_, Postgres>>>`

Test container is a 3rd party library which I don't have much control. I wonder how to deal with such cases when using tokio. Simply wrapping things into Arc and Mutex does not work.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source