Add wasm32-unknown-unknown compilation target support for matrix_sdk_sqlite#6329
Add wasm32-unknown-unknown compilation target support for matrix_sdk_sqlite#6329NoManColonies wants to merge 22 commits intomatrix-org:mainfrom
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #6329 +/- ##
==========================================
- Coverage 89.88% 89.87% -0.02%
==========================================
Files 376 376
Lines 103093 103097 +4
Branches 103093 103097 +4
==========================================
- Hits 92670 92658 -12
- Misses 6863 6870 +7
- Partials 3560 3569 +9 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Thanks very much for submitting this. We're quite excited by it, as it opens the door to things like being able to use the wasm bindings for matrix-sdk-crypto in node.js (matrix-org/matrix-sdk-crypto-wasm#168), and maybe even dropping support for indexeddb altogether.
Some questions, other than those below:
-
How were you able to test/build this? I tried things like
cargo check -p matrix-sdk-sqlite --target wasm32-unknown-unknownandwasm-pack test --chrome --headless crates/matrix-sdk-sqlite, and got build errors.Would you be able to add support to
cargo xtask cifor checking and testingmatrix-sdk-sqlitewith the wasm target? I think you'll need to add a new entry toWasmFeatureSet. -
Would you be able to break the changes down into smaller commits, to make them easier to review?
|
@NoManColonies I assume you're still working on this. Once it's ready for review, please rebase your changes on |
5e409c1 to
bf489aa
Compare
Thank you very much for taking your time to review this PR and apologize for the late reply.
I initially tested the prototype in a temporary downstream project and I seem to have forgotten to properly configure the feature requirements in the upstream crate, my apologies. You should be able to build and test with the following commands:
I’ve added tests as requested, but current VFS backend (OPFS) require dedicated worker context and is therefore not supported in a
Apologies for the large initial commit, it was initially composed of many small commit that didn’t compile. I saw a note in CONTRIBUTING.md that requires all commits to compile successfully, and all initial changes were required in order to compile under WASM targets. If you'd prefer, I can break the initial commit down into a smaller one. Since your previous comments, I have made the following changes:
If you have additional requests, please let know. |
chore: address breaking changes from rusqlite feat: support alternative v/fs for wasm environment feat: support non-send future for wasm environment fix: solve incorrect error transformation feat: WIP support connection pool in wasm environment fix: use full-path method call for wasm environment + other fixes for wasm fix: more wasm related fixes feat: use RefCell to simulate interior-mutability in wasm environment fix: use implicit borrow instead of explicit call to `as_ref()` fix: more wasm related fixes fix: resolve ambiguity between lock guard and ref cell implicit reference + more wasm fixes fix: resolve wasm related lifetime issues chore: turn on serde feature for web time when compiled as wasm32 target chore: ran cargo check to verify Cargo.lock file chore: fix comment formatting
…g conditional compilation
richvdh
left a comment
There was a problem hiding this comment.
Thanks very much for the updates. I've taken a more detailed look. Generally it looks great, but I have some comments.
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| //! An implementation of `deadpool` for `rusqlite` for usage |
There was a problem hiding this comment.
It doesn't really implement the whole of deadpool, it's just a manager.
| //! An implementation of `deadpool` for `rusqlite` for usage | |
| //! An implementation of `deadpool::managed::Manager` for `rusqlite` for usage |
| // limitations under the License. | ||
|
|
||
| //! An implementation of `deadpool` for `rusqlite` for usage | ||
| //! in WASM environment. |
There was a problem hiding this comment.
| //! in WASM environment. | |
| //! in WASM environments. |
| //! Similar to the one implemented in `crate::connection::default`, | ||
| //! we do not implement connection recycling here. Mostly due to | ||
| //! [`managed::Manager`] trait expecting a future output with `Send` | ||
| //! bound which is not available in WASM environment. |
There was a problem hiding this comment.
I don't really understand this comment. What does "do not implement connection recycling" mean? In what sense does Manager expect a future with Send?
| /// The default runtime used by `matrix-sdk-sqlite` for `deadpool`. | ||
| pub const RUNTIME: Runtime = Runtime::Tokio1; | ||
|
|
||
| deadpool::managed_reexports!( | ||
| "matrix-sdk-sqlite", | ||
| Manager, | ||
| managed::Object<Manager>, | ||
| rusqlite::Error, | ||
| Infallible | ||
| ); | ||
|
|
||
| /// Type representing a connection to SQLite from the [`Pool`]. | ||
| pub type Connection = Object; |
There was a problem hiding this comment.
Since this is the same in both implementations, maybe it could live in mod.rs?`
| } | ||
| .await | ||
| } | ||
| } |
There was a problem hiding this comment.
I think this should probably live in connection::wasm
There was a problem hiding this comment.
(and it probably needs a clearer name. I think probably just ConnectionWrapper would be fine, given it will be inside the connection::wasm module)
| if let Some(WasmFeatureSet::Sqlite) = cmd { | ||
| // Current VFS backend is not supported in Node.JS just yet. | ||
| // We force them to run in browser only for now. | ||
| run_wasm_pack_tests(Some(WasmFeatureSet::SqliteAllFeatures), WasmTestRunner::Chrome)?; | ||
| run_wasm_pack_tests(Some(WasmFeatureSet::SqliteAllFeatures), WasmTestRunner::Firefox)?; | ||
| run_wasm_pack_tests(Some(WasmFeatureSet::SqliteCache), WasmTestRunner::Chrome)?; | ||
| run_wasm_pack_tests(Some(WasmFeatureSet::SqliteCache), WasmTestRunner::Firefox)?; | ||
| run_wasm_pack_tests(Some(WasmFeatureSet::SqliteState), WasmTestRunner::Chrome)?; | ||
| run_wasm_pack_tests(Some(WasmFeatureSet::SqliteState), WasmTestRunner::Firefox)?; | ||
| run_wasm_pack_tests(Some(WasmFeatureSet::SqliteCrypto), WasmTestRunner::Chrome)?; | ||
| run_wasm_pack_tests(Some(WasmFeatureSet::SqliteCrypto), WasmTestRunner::Firefox)?; | ||
| return Ok(()); | ||
| } |
There was a problem hiding this comment.
can you put this next to the indexeddb equivalent?
| # [m]-sqlite is not supported on Node.js yet, due to | ||
| # dedicated worker requirement for OPFS |
There was a problem hiding this comment.
I don't think this matters here.
| # [m]-sqlite is not supported on Node.js yet, due to | |
| # dedicated worker requirement for OPFS |
| // SQLite WASM test suites has to be ran in release mode due to | ||
| // a harmless debug assertion when closing database. | ||
| // | ||
| // Ref: https://github.com/Spxg/sqlite-wasm-rs/blob/master/crates/sqlite-wasm-vfs/src/sahpool.rs#L672 |
There was a problem hiding this comment.
why does this happen? The assertion is "close without open", but doesn't the database file get opened?
| # Required in order to compile SQLite to WebAssembly | ||
| - name: Install emscripten toolchains | ||
| run: | | ||
| git clone https://github.com/emscripten-core/emsdk.git | ||
| cd emsdk | ||
| ./emsdk install latest | ||
| ./emsdk activate latest |
There was a problem hiding this comment.
This doesn't seem to be necessary when I run this locally. Are you sure it's needed?
Before starting, I apologize for any inconvenience caused by my non-native English.
This PR adds support for compiling
matrix_sdk_sqliteto thewasm32-unknown-unknowntarget, enabling use in browser and similar WASM environments.Currently,
matrix_sdkin WASM is limited to:This means persistent event/media caching is not available without a custom implementation.
This PR introduces SQLite-backed persistence for WASM as an additional store option.
Summary of changes
0.38(addswasm32-unknown-unknownsupport viasqlite-wasm-rs)cachefeature now required for prepared/cached statementsfallible_uintfeature required for unsigned integer castingwasm32-wasi-vfsfeature for WASM targets to enable a browser-compatible VFSweb-timedependency for media retention policy serializationfsfeature anddeadpool-syncbehind non-WASM targetsSendwithSendOutsideWasmwhere required for non-Send WASM environments#[cfg_attr(...)]instead of unconditional#[async_trait]for target-specific behaviorSyncWrapper<T>withRefCell<T>in the WASMdeadpooladapterSyncWrapper<T>requiresSendboundRefCell<T>provides equivalent interior mutability withoutSendboundNotes for reviewers
jsfeature is needed in order to compile to WASM targettarget_family = "wasm"CHANGELOG.mdfilesSigned-off-by: Geng Kongpop geng@finnomena.com