Skip to content
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

IndexedDB views backend #1630

Merged
merged 2 commits into from
Apr 3, 2024
Merged

IndexedDB views backend #1630

merged 2 commits into from
Apr 3, 2024

Conversation

Twey
Copy link
Contributor

@Twey Twey commented Feb 6, 2024

Motivation

#1610

Proposal

Add an IndexedDB storage backend to linera-views.

This branch uses a patched fork of indexed_db_futures because of Alorel/rust-indexed-db#34, which will otherwise break our non-Web Wasm build.

Test Plan

A set of tests is added to CI.

Release Plan

No user-visible changes (yet).

Links

@Twey Twey force-pushed the 02-06-IndexedDB_storage branch 7 times, most recently from 41cd210 to 41dba18 Compare February 7, 2024 18:32
@Twey Twey force-pushed the 02-06-IndexedDB_storage branch 2 times, most recently from 87ba6b0 to 4dc6352 Compare March 28, 2024 19:44
@Twey Twey force-pushed the 02-06-IndexedDB_storage branch from 4dc6352 to 20a491a Compare April 2, 2024 15:43
@Twey Twey marked this pull request as ready for review April 2, 2024 15:44
@Twey Twey force-pushed the 02-06-IndexedDB_storage branch 5 times, most recently from 607ddb5 to 054c492 Compare April 2, 2024 17:22
@Twey Twey requested review from MathieuDutSik and ma2bd April 2, 2024 20:03
@Twey Twey changed the title IndexedDB storage backend IndexedDB views backend Apr 3, 2024
Copy link
Contributor

@MathieuDutSik MathieuDutSik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason for web to be a priori different from indexed_db?

@@ -37,7 +37,7 @@ permissions:
jobs:
test:
runs-on: ubuntu-latest-16-cores
timeout-minutes: 90
timeout-minutes: 95
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that still needed, I thought that we decreased the need for such long times.

Copy link
Contributor Author

@Twey Twey Apr 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know where the 90 came from, but the +5 accounts (with a little wiggle room) for the runtime of wasm-pack test on my laptop.

/// The number of streams for the test
pub const TEST_INDEX_DB_MAX_STREAM_QUERIES: usize = 10;

const DATABASE_NAME: &str = "linera-views";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That seems inadequate. Within the framework of this library, all databases could claim to be linera-views. Why not use IndexedDB?

Copy link
Contributor

@ma2bd ma2bd Apr 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect this is a name provided to the (multi-application) database operated by the browser.

"linera" is perhaps a bit more precise because we sometime use a linera-views KV store directly (without views) e.g. to store certificates.

Copy link
Contributor Author

@Twey Twey Apr 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Within IndexedDB, all databases can claim to be IndexedDB :) As the name of an IndexedDB database, this key is namespaced within IndexedDB, not within linera-views — though actually, since IndexedDB is automatically isolated between domains, this whole string is essentially arbitrary (we don't need to distinguish it from anything else).

Comment on lines +145 to +155
loop {
let Some(key) = cursor.primary_key() else {
break;
};
let key = js_sys::Uint8Array::new(&key);
key_values.push((
key.subarray(key_prefix.len() as u32, key.length()).to_vec(),
js_sys::Uint8Array::new(&cursor.value()).to_vec(),
));
if !cursor.continue_cursor()?.await? {
break;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a little bit puzzling that the find_key_values_by_prefix implementation is significantly different from the find_keys_by_prefix. Is it questions of ownership?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's because the IndexedDB API has a convenient one-shot function for getting a range of keys, or a range of values, but not for getting both keys and values. Rather than perform one query to get the list of keys and then n queries to get a value for each key, I fell back to the slightly lower-level cursor API, which does allow getting both keys and values.

@Twey
Copy link
Contributor Author

Twey commented Apr 3, 2024

Is there a reason for web to be a priori different from indexed_db?

web (used across the workspace) only indicates that we're compiling for the Web target, i.e. browser APIs are available. We may wish to have different storage APIs on the Web, in the same way we support several different storage solutions on Linux. IndexedDB requires the Web, to a first approximation, but there's no need for the Web to require IndexedDB. Indeed, compiling with web but not indexeddb currently works, and gives you a linera-views that can only use the memory store :)

Ideally I think that wasm32-web or similar should be a compiler target, rather than a feature, but currently it doesn't exist. The Rust team are holding off on adding a plethora of Wasm targets until the dust settles a bit.

/// The number of streams for the test
pub const TEST_INDEX_DB_MAX_STREAM_QUERIES: usize = 10;

const DATABASE_NAME: &str = "linera-views";
Copy link
Contributor

@ma2bd ma2bd Apr 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect this is a name provided to the (multi-application) database operated by the browser.

"linera" is perhaps a bit more precise because we sometime use a linera-views KV store directly (without views) e.g. to store certificates.

@Twey Twey force-pushed the 02-06-IndexedDB_storage branch 2 times, most recently from 5b2bf71 to 7b3ae7d Compare April 3, 2024 14:32
Twey added 2 commits April 3, 2024 15:41
Use `indexed_db_futures` to implement
`Local{Readable,Writable,Admin}KeyValueStore`.

`indexed_db_futures` is a little inconveniently low-level, but seems
to be by far the most widely-used crate for IndexedDB in Rust, so
should remain supported for some time.
@Twey Twey force-pushed the 02-06-IndexedDB_storage branch from 7b3ae7d to 50101be Compare April 3, 2024 14:41
@Twey Twey requested review from ma2bd and MathieuDutSik April 3, 2024 15:24
Copy link
Contributor

@MathieuDutSik MathieuDutSik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the good work.

@Twey Twey merged commit f98ce09 into linera-io:main Apr 3, 2024
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Add IndexedDB backend for linera-storage
4 participants