Make RocksDB integration more, if not completely, sound (#77)

Closes #76
This commit is contained in:
Finn Bear 2022-08-31 06:18:23 -07:00 committed by GitHub
parent 960061584d
commit 8907f0aa14
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 3 deletions

View file

@ -64,7 +64,7 @@ url = "2.2.2"
uuid = { version = "1.1.2", features = ["serde", "v4"] }
[dev-dependencies]
tokio = { version = "1.20.1", features = ["macros"] }
tokio = { version = "1.20.1", features = ["macros", "rt"] }
[target.'cfg(target_arch = "wasm32")'.dependencies]
surf = { version = "2.3.2", optional = true, default-features = false, features = ["encoding", "wasm-client"] }

View file

@ -9,10 +9,11 @@ use rocksdb::IteratorMode;
use rocksdb::OptimisticTransactionDB;
use rocksdb::ReadOptions;
use std::ops::Range;
use std::pin::Pin;
use std::sync::Arc;
pub struct Datastore {
db: rocksdb::OptimisticTransactionDB,
db: Pin<Arc<rocksdb::OptimisticTransactionDB>>,
}
pub struct Transaction {
@ -22,13 +23,16 @@ pub struct Transaction {
rw: bool,
// The distributed datastore transaction
tx: Arc<Mutex<Option<rocksdb::Transaction<'static, OptimisticTransactionDB>>>>,
// the above, supposedly 'static, transaction actually points here, so keep the memory alive
// note that this is dropped last, as it is declared last
_db: Pin<Arc<rocksdb::OptimisticTransactionDB>>,
}
impl Datastore {
// Open a new database
pub async fn new(path: &str) -> Result<Datastore, Error> {
Ok(Datastore {
db: OptimisticTransactionDB::open_default(path)?,
db: Arc::pin(OptimisticTransactionDB::open_default(path)?),
})
}
// Start a new transaction
@ -52,6 +56,7 @@ impl Datastore {
ok: false,
rw: write,
tx: Arc::new(Mutex::new(Some(tx))),
_db: self.db.clone(),
})
}
}
@ -286,3 +291,18 @@ impl Transaction {
Ok(res)
}
}
#[cfg(test)]
mod tests {
// https://github.com/surrealdb/surrealdb/issues/76
#[tokio::test]
async fn soundness() {
let mut transaction = get_transaction().await;
transaction.put("uh", "oh").await.unwrap();
async fn get_transaction() -> crate::Transaction {
let datastore = crate::Datastore::new("rocksdb:/tmp/rocks.db").await.unwrap();
datastore.transaction(true, false).await.unwrap()
}
}
}