leveldb-rs icon indicating copy to clipboard operation
leveldb-rs copied to clipboard

| |_^ `(dyn KeyValueDb + 'static)` cannot be shared between threads safely

Open shangsony opened this issue 3 years ago • 6 comments

| 12 | / lazy_static! { 13 | | pub static ref StorageInstanceRef:RwLock<StorageFactory> = RwLock::new(StorageFactory::default()); 14 | | } | |_^ (dyn KeyValueDb + 'static) cannot be shared between threads safely | ::: C:\Users\Song.Shang.cargo\registry\src\mirrors.tuna.tsinghua.edu.cn-df7c3c540f42cdbd\lazy_static-1.4.0\src\inline_lazy.rs:19:20 | 19 | pub struct Lazy<T: Sync>(Cell<Option<T>>, Once); | ---- required by this bound in lazy_static::lazy::Lazy | = help: the trait Sync is not implemented for (dyn KeyValueDb + 'static) = note: required because of the requirements on the impl of Sync for parking_lot::lock_api::RwLock<parking_lot::RawRwLock, (dyn KeyValueDb + 'static)> = note: required because of the requirements on the impl of Send for Arc<parking_lot::lock_api::RwLock<parking_lot::RawRwLock, (dyn KeyValueDb + 'static)>> = note: required because it appears within the type StorageFactory = note: required because of the requirements on the impl of Sync for parking_lot::lock_api::RwLock<parking_lot::RawRwLock, StorageFactory> = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 2 previous errors; 2 warnings emitted

For more information about this error, try rustc --explain E0277. error: could not compile storage

shangsony avatar Jul 05 '21 07:07 shangsony

Hm, I don't think this is a problem in this crate?

dermesser avatar Jul 05 '21 07:07 dermesser

Can I replace Rc with an Arc pointer for multithreading

shangsony avatar Jul 06 '21 03:07 shangsony

Same question here, maybe Arc will bring more performance loss?

KunoiSayami avatar Aug 22 '23 16:08 KunoiSayami

Hm, I don't think this is a problem in this crate?

It's this crate's problem, in my cases

error: future cannot be sent between threads safely
   --> src/hypervisor.rs:99:49
    |
99  |           let auto_channel_handler = tokio::spawn(staff(
    |  _________________________________________________^
105 | |         ));
    | |_________^ future returned by `staff` is not `Send`
    |
    = help: within `impl futures_util::Future<Output = std::result::Result<(), anyhow::Error>>`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<rusty_leveldb::CompressorList>`
note: future is not `Send` as this value is used across an await
   --> src/plugins/kv.rs:30:88
    |
30  |             Self::new_leveldb_with_option(level_db, rusty_leveldb::Options::default()).await
    |                                                     ---------------------------------  ^^^^^ await occurs here, with `rusty_leveldb::Options::default()` maybe used later
    |                                                     |
    |                                                     has type `rusty_leveldb::Options` which is not `Send`
31  |         }
    |         - `rusty_leveldb::Options::default()` is later dropped here
note: required by a bound in `tokio::spawn`
   --> /home/user/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/task/spawn.rs:166:21
    |
164 |     pub fn spawn<T>(future: T) -> JoinHandle<T::Output>
    |            ----- required by a bound in this function
165 |     where
166 |         T: Future + Send + 'static,
    |                     ^^^^ required by this bound in `spawn`

And after checking your code, this problem seem cause by:

pub cmp: Rc<Box<dyn Cmp>>,
pub env: Rc<Box<dyn Env>>,
pub log: Option<Rc<RefCell<Logger>>>,

Which Rc is not allow Send.

So, can we just simply replace Rc with an Arc pointer for multithreading?

KunoiSayami avatar Aug 22 '23 16:08 KunoiSayami

Maybe I'm doing something wrong and it doesn't work this way. I tried simply replace Rc with Arc but rustc still complain me. Test passed version: https://github.com/KunoiSayami/leveldb-rs-arc

KunoiSayami avatar Aug 22 '23 17:08 KunoiSayami

Well, overall leveldb-rs is made to run on a single thread. So this is intended behavior. I have started work (but not recently continued) on a wrapper suitable for use in asynchronous contexts, which may work for you too (src/asyncdb.rs).

dermesser avatar Aug 23 '23 19:08 dermesser