From f628df91bade6787817e3de16888be1b5bc9949f Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Mon, 11 Nov 2019 15:27:43 +0100 Subject: [PATCH 1/3] kvdb-web: async-awaitify --- kvdb-web/Cargo.toml | 11 ++-- kvdb-web/src/lib.rs | 113 +++++++++++++---------------------- kvdb-web/tests/indexed_db.rs | 56 ++++++++--------- 3 files changed, 70 insertions(+), 110 deletions(-) diff --git a/kvdb-web/Cargo.toml b/kvdb-web/Cargo.toml index aaf237da8..be356815f 100644 --- a/kvdb-web/Cargo.toml +++ b/kvdb-web/Cargo.toml @@ -9,8 +9,8 @@ license = "GPL-3.0" edition = "2018" [dependencies] -wasm-bindgen = "0.2.51" -js-sys = "0.3.28" +wasm-bindgen = "0.2.54" +js-sys = "0.3.31" kvdb = { version = "0.1", path = "../kvdb" } kvdb-memorydb = { version = "0.1", path = "../kvdb-memorydb" } futures-preview = "0.3.0-alpha.19" @@ -18,7 +18,7 @@ log = "0.4.8" send_wrapper = "0.3.0" [dependencies.web-sys] -version = "0.3.28" +version = "0.3.31" features = [ 'console', 'Window', @@ -37,7 +37,6 @@ features = [ ] [dev-dependencies] -wasm-bindgen-test = "0.2.49" -futures-preview = { version = "0.3.0-alpha.19", features = ['compat'] } -futures01 = { package = "futures", version = "0.1" } +wasm-bindgen-test = "0.3.4" console_log = "0.1.2" +wasm-bindgen-futures = "0.4.4" diff --git a/kvdb-web/src/lib.rs b/kvdb-web/src/lib.rs index bc9687ed4..f2a3bede4 100644 --- a/kvdb-web/src/lib.rs +++ b/kvdb-web/src/lib.rs @@ -28,8 +28,6 @@ use kvdb::{DBTransaction, DBValue}; use kvdb_memorydb::{self as in_memory, InMemory}; use send_wrapper::SendWrapper; use std::io; -use std::rc::Rc; -use std::sync::Mutex; pub use error::Error; pub use kvdb::KeyValueDB; @@ -44,7 +42,7 @@ pub struct Database { version: u32, columns: u32, in_memory: InMemory, - indexed_db: Mutex>, + indexed_db: SendWrapper, } // The default column is represented as `None`. @@ -57,71 +55,44 @@ fn number_to_column(col: u32) -> Column { impl Database { /// Opens the database with the given name, /// and the specified number of columns (not including the default one). - pub fn open(name: String, columns: u32) -> impl Future> { - // let's try to open the latest version of the db first - let open_request = indexed_db::open(name.as_str(), None, columns); + pub async fn open(name: String, columns: u32) -> Result { let name_clone = name.clone(); - open_request - .then(move |db| { - let db = match db { - Ok(db) => db, - Err(err) => return future::Either::Right(future::err(err)), - }; - - // If we need more column than the latest version has, - // then bump the version (+ 1 for the default column). - // In order to bump the version, we close the database - // and reopen it with a higher version than it was opened with previously. - // cf. https://github.com/paritytech/parity-common/pull/202#discussion_r321221751 - if columns + 1 > db.columns { - let next_version = db.version + 1; - drop(db); - future::Either::Left(indexed_db::open(name.as_str(), Some(next_version), columns).boxed()) - } else { - future::Either::Left(future::ok(db).boxed()) - } - // populate the in_memory db from the IndexedDB - }) - .then(move |db| { - let db = match db { - Ok(db) => db, - Err(err) => return future::Either::Right(future::err(err)), - }; - - let indexed_db::IndexedDB { version, inner, .. } = db; - let rc = Rc::new(inner.take()); - let weak = Rc::downgrade(&rc); - // read the columns from the IndexedDB - future::Either::Left( - stream::iter(0..=columns) - .map(move |n| { - let db = weak.upgrade().expect("rc should live at least as long; qed"); - indexed_db::idb_cursor(&db, n).fold(DBTransaction::new(), move |mut txn, (key, value)| { - let column = number_to_column(n); - txn.put_vec(column, key.as_ref(), value); - future::ready(txn) - }) - // write each column into memory - }) - .fold(in_memory::create(columns), |m, txn| { - txn.then(|txn| { - m.write_buffered(txn); - future::ready(m) - }) - }) - .then(move |in_memory| { - future::ok(Database { - name: name_clone, - version, - columns, - in_memory, - indexed_db: Mutex::new(SendWrapper::new( - Rc::try_unwrap(rc).expect("should have only 1 ref at this point; qed"), - )), - }) - }), - ) - }) + // let's try to open the latest version of the db first + let db = indexed_db::open(name.as_str(), None, columns).await?; + + // If we need more column than the latest version has, + // then bump the version (+ 1 for the default column). + // In order to bump the version, we close the database + // and reopen it with a higher version than it was opened with previously. + // cf. https://github.com/paritytech/parity-common/pull/202#discussion_r321221751 + let db = if columns + 1 > db.columns { + let next_version = db.version + 1; + drop(db); + indexed_db::open(name.as_str(), Some(next_version), columns).await? + } else { + db + }; + // populate the in_memory db from the IndexedDB + let indexed_db::IndexedDB { version, inner, .. } = db; + let in_memory = in_memory::create(columns); + // read the columns from the IndexedDB + for n in 0..=columns { + let column = number_to_column(n); + let mut txn = DBTransaction::new(); + let mut stream = indexed_db::idb_cursor(&*inner, n); + while let Some((key, value)) = stream.next().await { + txn.put_vec(column, key.as_ref(), value); + } + // write each column into memory + in_memory.write_buffered(txn); + } + Ok(Database { + name: name_clone, + version, + columns, + in_memory, + indexed_db: inner, + }) } /// Get the database name. @@ -137,9 +108,7 @@ impl Database { impl Drop for Database { fn drop(&mut self) { - if let Ok(db) = self.indexed_db.lock() { - db.close(); - } + self.indexed_db.close(); } } @@ -153,9 +122,7 @@ impl KeyValueDB for Database { } fn write_buffered(&self, transaction: DBTransaction) { - if let Ok(guard) = self.indexed_db.lock() { - let _ = indexed_db::idb_commit_transaction(&*guard, &transaction, self.columns); - } + let _ = indexed_db::idb_commit_transaction(&*self.indexed_db, &transaction, self.columns); self.in_memory.write_buffered(transaction); } diff --git a/kvdb-web/tests/indexed_db.rs b/kvdb-web/tests/indexed_db.rs index 0824a5760..a440e3613 100644 --- a/kvdb-web/tests/indexed_db.rs +++ b/kvdb-web/tests/indexed_db.rs @@ -16,52 +16,46 @@ //! IndexedDB tests. -use futures::compat; -use futures::future::{self, FutureExt as _, TryFutureExt as _}; +use futures::future::TryFutureExt as _; use kvdb_web::{Database, KeyValueDB as _}; -use wasm_bindgen::JsValue; use wasm_bindgen_test::*; wasm_bindgen_test_configure!(run_in_browser); -#[wasm_bindgen_test(async)] -fn reopen_the_database_with_more_columns() -> impl futures01::Future { +#[wasm_bindgen_test] +async fn reopen_the_database_with_more_columns() { let _ = console_log::init_with_level(log::Level::Trace); - fn open_db(col: u32) -> impl future::Future { - Database::open("MyAsyncTest".into(), col).unwrap_or_else(|err| panic!("{}", err)) + async fn open_db(col: u32) -> Database { + Database::open("MyAsyncTest".into(), col) + .unwrap_or_else(|err| panic!("{}", err)) + .await } - let fut = open_db(1) - .then(|db| { - // Write a value into the database - let mut batch = db.transaction(); - batch.put(None, b"hello", b"world"); - db.write_buffered(batch); + let db = open_db(1).await; + + // Write a value into the database + let mut batch = db.transaction(); + batch.put(None, b"hello", b"world"); + db.write_buffered(batch); - assert_eq!(db.get(None, b"hello").unwrap().unwrap().as_ref(), b"world"); + assert_eq!(db.get(None, b"hello").unwrap().unwrap().as_ref(), b"world"); - // Check the database version - assert_eq!(db.version(), 1); + // Check the database version + assert_eq!(db.version(), 1); - // Close the database - drop(db); + // Close the database + drop(db); - // Reopen it again with 3 columns - open_db(3) - }) - .map(|db| { - // The value should still be present - assert_eq!(db.get(None, b"hello").unwrap().unwrap().as_ref(), b"world"); - assert!(db.get(None, b"trash").unwrap().is_none()); + // Reopen it again with 3 columns + let db = open_db(3).await; - // The version should be bumped - assert_eq!(db.version(), 2); + // The value should still be present + assert_eq!(db.get(None, b"hello").unwrap().unwrap().as_ref(), b"world"); + assert!(db.get(None, b"trash").unwrap().is_none()); - Ok(()) - }); - - compat::Compat::new(fut) + // The version should be bumped + assert_eq!(db.version(), 2); } From 5a862c063ad492530d52443b83668ecdee8962aa Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Mon, 11 Nov 2019 15:30:59 +0100 Subject: [PATCH 2/3] kvdb-web: cargo fmt --- kvdb-web/src/lib.rs | 10 ++-------- kvdb-web/tests/indexed_db.rs | 6 ++---- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/kvdb-web/src/lib.rs b/kvdb-web/src/lib.rs index f2a3bede4..946057830 100644 --- a/kvdb-web/src/lib.rs +++ b/kvdb-web/src/lib.rs @@ -80,19 +80,13 @@ impl Database { let column = number_to_column(n); let mut txn = DBTransaction::new(); let mut stream = indexed_db::idb_cursor(&*inner, n); - while let Some((key, value)) = stream.next().await { + while let Some((key, value)) = stream.next().await { txn.put_vec(column, key.as_ref(), value); } // write each column into memory in_memory.write_buffered(txn); } - Ok(Database { - name: name_clone, - version, - columns, - in_memory, - indexed_db: inner, - }) + Ok(Database { name: name_clone, version, columns, in_memory, indexed_db: inner }) } /// Get the database name. diff --git a/kvdb-web/tests/indexed_db.rs b/kvdb-web/tests/indexed_db.rs index a440e3613..2a9ddc14e 100644 --- a/kvdb-web/tests/indexed_db.rs +++ b/kvdb-web/tests/indexed_db.rs @@ -29,13 +29,11 @@ async fn reopen_the_database_with_more_columns() { let _ = console_log::init_with_level(log::Level::Trace); async fn open_db(col: u32) -> Database { - Database::open("MyAsyncTest".into(), col) - .unwrap_or_else(|err| panic!("{}", err)) - .await + Database::open("MyAsyncTest".into(), col).unwrap_or_else(|err| panic!("{}", err)).await } let db = open_db(1).await; - + // Write a value into the database let mut batch = db.transaction(); batch.put(None, b"hello", b"world"); From 1de1037afbfc294ec3a69ec2523a1efb442b28c8 Mon Sep 17 00:00:00 2001 From: Andronik Ordian Date: Tue, 19 Nov 2019 16:50:58 +0100 Subject: [PATCH 3/3] Update kvdb-web/Cargo.toml --- kvdb-web/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kvdb-web/Cargo.toml b/kvdb-web/Cargo.toml index be356815f..c9157d922 100644 --- a/kvdb-web/Cargo.toml +++ b/kvdb-web/Cargo.toml @@ -13,7 +13,7 @@ wasm-bindgen = "0.2.54" js-sys = "0.3.31" kvdb = { version = "0.1", path = "../kvdb" } kvdb-memorydb = { version = "0.1", path = "../kvdb-memorydb" } -futures-preview = "0.3.0-alpha.19" +futures = "0.3" log = "0.4.8" send_wrapper = "0.3.0"