Switch indexeddb backend to sqlite and improve IPC messaging (#38187)

- Use sqlite instead of heed. (one indexed database = one sqlite
database)
- Implement the backend for indexes
- Use keyranges where needed (as specified by the spec)
- Implement `getKey`
- Fix channel error messaging (led to a bunch of changes to how async
requests are handled)

Note: `components/net/indexeddb/engines/sqlite/serialize.rs` is unused;
I can delete it if needed.

Testing: Switching to sqlite eliminated many panics (exposing some new
failures).
Fixes: #38040

---------

Signed-off-by: Ashwin Naren <arihant2math@gmail.com>
This commit is contained in:
Ashwin Naren 2025-08-16 00:27:17 -07:00 committed by GitHub
parent f4bbdf8010
commit fc3feceee5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
59 changed files with 2002 additions and 818 deletions

View file

@ -4,15 +4,14 @@
use std::collections::VecDeque;
use ipc_channel::ipc::IpcSender;
use net_traits::indexeddb_thread::{AsyncOperation, IdbResult, IndexedDBTxnMode};
use net_traits::indexeddb_thread::{AsyncOperation, CreateObjectResult, IndexedDBTxnMode, KeyPath};
use tokio::sync::oneshot;
pub use self::heed::HeedEngine;
pub use self::sqlite::SqliteEngine;
mod heed;
mod sqlite;
#[derive(Eq, Hash, PartialEq)]
#[derive(Clone, Eq, Hash, PartialEq)]
pub struct SanitizedName {
name: String,
}
@ -46,34 +45,57 @@ impl std::fmt::Display for SanitizedName {
}
pub struct KvsOperation {
pub sender: IpcSender<Result<Option<IdbResult>, ()>>,
pub store_name: SanitizedName,
pub operation: AsyncOperation,
}
pub struct KvsTransaction {
// Mode could be used by a more optimal implementation of transactions
// that has different allocated threadpools for reading and writing
#[allow(unused)]
pub mode: IndexedDBTxnMode,
pub requests: VecDeque<KvsOperation>,
}
pub trait KvsEngine {
type Error;
type Error: std::error::Error;
fn create_store(
&self,
store_name: SanitizedName,
key_path: Option<KeyPath>,
auto_increment: bool,
) -> Result<(), Self::Error>;
) -> Result<CreateObjectResult, Self::Error>;
fn delete_store(&self, store_name: SanitizedName) -> Result<(), Self::Error>;
#[expect(dead_code)]
fn close_store(&self, store_name: SanitizedName) -> Result<(), Self::Error>;
fn delete_database(self) -> Result<(), Self::Error>;
fn process_transaction(
&self,
transaction: KvsTransaction,
) -> oneshot::Receiver<Option<Vec<u8>>>;
fn has_key_generator(&self, store_name: SanitizedName) -> bool;
fn key_path(&self, store_name: SanitizedName) -> Option<KeyPath>;
fn create_index(
&self,
store_name: SanitizedName,
index_name: String,
key_path: KeyPath,
unique: bool,
multi_entry: bool,
) -> Result<CreateObjectResult, Self::Error>;
fn delete_index(
&self,
store_name: SanitizedName,
index_name: String,
) -> Result<(), Self::Error>;
fn version(&self) -> Result<u64, Self::Error>;
fn set_version(&self, version: u64) -> Result<(), Self::Error>;
}