State
HTTPリクエストに渡すロケットを使用しています。この構造体にはMutex<DatastoreInstance>
、SQLite データベースへのアクセスを提供する が含まれており、読み取りと書き込みを安全にするためにミューテックスでロックされています。
pub struct DatastoreInstance {
conn: Connection,
}
構造体がこのように見えたとき、DatastoreInstance
SQLite 接続のみですべてが正常に機能しましたが、この構造体内にトランザクション オブジェクトも追加したいと考えました。
pub struct DatastoreInstance {
conn: Connection,
events_transaction: Transaction,
}
これはコンパイルされませんでした。これは、オブジェクトが認識している有効期間を持つオブジェクトTransaction
を参照する必要があるためです。私が使用している rusqlite 内Connection
のオブジェクトConnection
とオブジェクトは次のように定義されています。Transaction
pub struct Connection {
db: RefCell<InnerConnection>,
cache: StatementCache,
path: Option<PathBuf>,
}
pub struct Transaction<'conn> {
conn: &'conn Connection,
drop_behavior: DropBehavior,
}
有効期間の問題を解決するには、これらの有効期間パラメーターを追加して機能させる必要がありました。
pub struct DatastoreInstance<'a> {
conn: Connection,
events_transaction: Transaction<'a>,
}
これは結果であり、ライフタイムとミューテックスの両方の理解に従って動作するはずでしたが、次のようなコンパイラ エラーが表示されます。
`std::cell::RefCell<lru_cache::LruCache<std::string::String, rusqlite::raw_statement::RawStatement>>` cannot be shared between threads safely
|
= help: within `rusqlite::Connection`, the trait `std::marker::Sync` is not implemented for `std::cell::RefCell<lru_cache::LruCache<std::string::String, rusqlite::raw_statement::RawStatement>>`
= note: required because it appears within the type `rusqlite::cache::StatementCache`
= note: required because it appears within the type `rusqlite::Connection`
= note: required because of the requirements on the impl of `std::marker::Send` for `&rusqlite::Connection`
= note: required because it appears within the type `datastore::DatastoreInstance<'_>`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::sync::Mutex<datastore::DatastoreInstance<'_>>`
= note: required because it appears within the type `endpoints::ServerState<'_>`
= note: required by `rocket::State`
DatastoreInstance
ミューテックスに関する私の理解によれば、構造体全体が にラップされているため、このコードは有効である必要がありますMutex
。これにより、一度に 1 つのスレッドのみがこのオブジェクトを参照することが保証されます。
私は何が欠けていますか?
a 内だけではなく、a 内で参照RefCell
されている内にいると、コンパイラがもう安全であると判断しないのはなぜですか?Connection
Transaction
Connection
ミューテックスの仕組みをよく理解していませんか? 私のライフタイムは無効で、何らかの形で読み取り/書き込みの安全性が損なわれていますか? Connection
andを同じ構造内に持つ設計は、Transaction
読み取り/書き込みの安全性を損なう悪い設計ですか? これを安全にするために、何らかの形でデータ構造を再設計する必要がありますか? それとも、非常に明白な何かが欠けているだけですか?