-
Notifications
You must be signed in to change notification settings - Fork 225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[kvdb-web] indexeddb implementation #202
Conversation
kvdb-web/src/lib.rs
Outdated
} | ||
|
||
// TODO: is it safe for IdbDatabase? | ||
struct MakeSendSync<T>(T); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I generally use SendWrapper
from here: https://docs.rs/send_wrapper/0.2.0/send_wrapper/
As far as I know, it is unfortunately actually not safe to implement Sync
. If threads become usable one day, that will bite us.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is technically unsafe unless we only write in a single thread. I'm not sure what's the best way forward though, this Send + Sync
requirement is enforced by the KeyValueDB
trait.
We are forcing version alpha.17 in Substrate because of a compilation error with alpha.18. Co-Authored-By: Pierre Krieger <[email protected]>
kvdb-web/src/indexed_db.rs
Outdated
.expect_throw("IndexDB should be supported in your browser"); | ||
|
||
// TODO: don't hardcode version | ||
let open_request = indexed_db.open_with_u32(name, /* version */ 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are only two ways to handle this "version" thing here IMO: either we use the version, by passing it as parameter and adding a method to retrieve it later, or we don't pass any version at all.
I would go for no version at all.
let open_request = indexed_db.open_with_u32(name, /* version */ 1) | |
let open_request = indexed_db.open_with_u32(name) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently, if we reopen the database with more columns that it was opened previously, it will panic on open, when trying to create a transaction to read from a new column. Because a new column is expected to be created on version upgrade (try_create_object_stores
).
We can pass the number of columns as a version, sounds reasonable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it possible to dynamically check the number of columns, and add the missing ones?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tried that, but creating a column only possible onupgradeneeded:
The createObjectStore() method of the IDBDatabase interface creates and returns a new object store or index.
this method can be called only within a versionchange transaction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see! Then bump the version if we detect that the number of columns is different?
It might seem stupid, but I'd prefer to use things as they are intended to be used. In other words, the "version" should actually be a version and not a way for us to store a number.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then bump the version if we detect that the number of columns is different?
The version is bumped only when we open the db with a higher version. And we can query the version on after either the open requests succeeds or onupgradeneeded
is called (we specified a higher version that it is).
So I went with "by passing it as parameter and adding a method to retrieve it later" approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I went with "by passing it as parameter and adding a method to retrieve it later" approach.
What worries me is that nobody is probably ever going to use this mechanism.
RocksDB automatically updates the number of columns if it doesn't match the number on disk, and I'm not sure it's a good idea to force users to manage a database version number just for IndexedDB.
What is going to happen in practice is that people will constantly forget to bump the database version number. RocksDB will work just fine, so nobody will realize, but IndexedDB will break.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In parity-ethereum we have a separate version file stored for RocksDB, see https://github.com/paritytech/parity-ethereum/blob/master/parity/db/rocksdb/migration.rs and the it refuses to open the newer version.
We could open the latest version of the db, see the version and the number of columns, and if the we need more columns, close it and reopen with a different number of version. But that sounds like a hack.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW I've implemented this hacky solution.
* master: [plain_hasher] Migrate to 2018 edition (#213) [ethbloom] Improve ethbloom (#215) [rlp] fix nested unbounded lists (#203) stabilize parity-bytes in no_std environment (#212) Speed up hex serialization, support Serde `with`, and fix warnings (#208) [ethbloom, ethereum-types,kvdb] migrate to 2018 edition (#205) Introduce `ContractAddress` newtype instead of scheme enum (#200)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
The version hack is obviously not great, but it's the least bad solution IMO.
What's the next step? Does that need another review or can we merge? |
It needs another review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nits and a few more tests would be good, but otherwise lgtm.
Running
Using Chrome also fails with:
|
Not sure what to do with macOS, seems like wasm-pack issue to me. |
Ok, sounds like we should perhaps add a README where we list what combinations are "known good" (linux + chrome + ff I guess?) and call it a day? I mean, it doesn't seem like it should block the PR. An issue on the webpack repo linked from the README maybe? |
This is an alternative implementation for #182 based on IndexedDB (cc @tomaka).
Writes data both into memory and IndexedDB, reads from the IndexedDB on
open
.Closes #182.