dermesser / leveldb-rs

A reimplementation of LevelDB in Rust (no bindings).
Other
521 stars 59 forks source link

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

Open shangsony opened 3 years ago

shangsony commented 3 years ago
12 / lazy_static! { 13 pub static ref StorageInstanceRef:RwLock = 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(Cell<Option>, 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

dermesser commented 3 years ago

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

shangsony commented 3 years ago

Can I replace Rc with an Arc pointer for multithreading

KunoiSayami commented 1 year ago

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

KunoiSayami commented 1 year ago

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 commented 1 year ago

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

dermesser commented 1 year ago

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).