feat(core): replace rusqlite with turso 0.6.0-pre.26 (multi-process WAL)#35545
Draft
FrozenPandaz wants to merge 4 commits intomasterfrom
Draft
feat(core): replace rusqlite with turso 0.6.0-pre.26 (multi-process WAL)#35545FrozenPandaz wants to merge 4 commits intomasterfrom
FrozenPandaz wants to merge 4 commits intomasterfrom
Conversation
Replaces the rusqlite C-bindings backend with the pure-Rust turso crate (v0.6.0-pre.26), which now ships process-shared WAL coordination via the upstream tshm protocol (tursodatabase/turso#6236, merged 2026-04-20). The previous spike (#34933) closed because turso could not share a DB file across the daemon, CLI, and plugin workers. The new release fixes that, so the spike can land using a published crate version instead of a git-branch dependency. Removes the rusqlite-era retry/lock-file/WAL-negotiation/WSL1 detection machinery that existed solely to work around rusqlite concurrency edge cases; turso's busy_timeout + WAL handle the same cases natively. Cargo.toml: rusqlite 0.32.1 -> turso 0.6.0-pre.26 (no C deps, WASM-ready) db/initialize.rs: ~500 -> ~120 lines; open + WAL pragma + create tables db/connection.rs: turso::Connection wrapper with DbValue/DbRow shims db/mod.rs: drop lock-file dance; keep DB_VERSION filename + cleanup cache/cache.rs: port fetch_cache_rows from rarray to dynamic IN clause tasks/task_history.rs, details.rs, running_tasks_service.rs: DbValue params telemetry/mod.rs, service.rs: DbValue params, DbRow results Adds initialize_db_concurrent_connections test verifying two connections can simultaneously open and read/write the same DB file.
✅ Deploy Preview for nx-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for nx-dev ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Contributor
|
View your CI Pipeline Execution ↗ for commit 22afaea
☁️ Nx Cloud last updated this comment at |
Without this flag turso 0.6.0-pre.26 silently uses an in-process WAL backend, so a second OS process opening the same DB hits "File is locked by another process" — the same failure mode that killed the original spike (#34933). Note: with the flag set, the lock contention moves from .db to .db-wal but still rejects a second process in real daemon+CLI flows (verified via local two-process repro). Pushing anyway so CI can exercise the new code path on Linux x64 and we can see if the behavior is platform-specific or universally broken.
Previous run was canceled before e2e tests started, so we don't know whether experimental_multiprocess_wal(true) actually changed Linux behavior. Empty commit to re-fire the pipeline.
Confirmed via local two-process repro that the patch unlocks multi-process DB opens. Upstream pre.26 has a one-line bug in turso_sdk_kit/src/rsapi.rs: it computes open_flags with NoLock when experimental_multiprocess_wal is enabled, applies it to the initial .db file open, but then hardcodes OpenFlags::default() on the inner Database::open_with_flags_async call — which is what opens the .db-wal file with an exclusive lock that blocks every other process. Vendored copy of turso_sdk_kit-0.6.0-pre.26 lives under cargo-patches/, referenced via [patch.crates-io] in Cargo.toml. The only delta vs the registry source is in src/rsapi.rs around the Opening phase — search for "PATCH:" to find it. Drop this once upstream cuts a release with the fix.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Current Behavior
Nx uses
rusqlite(C SQLite bindings) with a hand-rolled retry/backoff/lock-file layer to handle SQLite concurrency across the daemon, CLI, and plugin workers. Rusqlite bundles C SQLite, which blocks WASM compilation and requires a C compiler for every target platform.Expected Behavior
Replace
rusqlitewith the publishedtursocrate (0.6.0-pre.26) — a pure-Rust SQLite rewrite. Primary motivation: WASM support. Turso has no C dependencies, so it can compile to WASM natively.Secondary benefits:
Statementtypes leaking through the codebaseThis rebases the closed spike #34933, which was closed because turso couldn't share a DB file across daemon + CLI + workers. Upstream tursodatabase/turso#6236 (merged 2026-04-20) added the multi-process
tshmWAL coordination protocol, and0.6.0-pre.26ships it.CI status: green
.dbexperimental_multiprocess_wal(true)only.db-walThe full
nx affected --targets=lint,test,build,e2e,e2e-ci,...pipeline passes (42m 27s, 250 e2e tasks ✔), with no "Locking error" / "Failed to open database" / "Corrupt coordination" anywhere in the logs.Why a vendored patch (and how to remove it)
turso 0.6.0-pre.26exposes the multi-process WAL feature viaBuilder::experimental_multiprocess_wal(true), butturso_sdk_kit-0.6.0-pre.26(a transitive dep that wires it up) has a one-line bug. Insrc/rsapi.rs:The result: the
.dbfile opens withNoLockcorrectly, but the.db-walfile (opened insideDatabase::open_with_flags_async) takes an exclusive lock anyway — defeating the multi-process feature. We see the lock just move from.dbto.db-walwhen the flag is enabled but the patch isn't.Workaround (this PR): vendor
turso_sdk_kitundercargo-patches/turso_sdk_kit/and reference it from the workspaceCargo.tomlvia[patch.crates-io]. The only delta vs the registry source is that one block insrc/rsapi.rs(search "PATCH:" in the file). 256K, 10 files.Removal: an upstream issue/PR with the diagnosis is being filed. Once turso publishes a release with the fix, drop
cargo-patches/, drop the[patch.crates-io]section, and bump thetursoversion. Tracked in the inline comment onCargo.toml.Files changed
Cargo.tomlrusqlite 0.32.1→turso 0.6.0-pre.26(no C deps, WASM-ready);[patch.crates-io]for the SDK fixcargo-patches/turso_sdk_kit/turso_sdk_kit-0.6.0-pre.26with one-line patch insrc/rsapi.rsdb/initialize.rsBuilder::new_local(...).experimental_multiprocess_wal(true).build()→ WAL pragma → busy_timeout → create tables. Drops the WSL1 / journal-mode / filesystem-diagnostics machinerydb/connection.rsturso::Connectionwrapper withDbValue/DbRowshimsdb/mod.rsbusy_timeout+ WAL handle multi-process directly. Keeps master's filename-based schema versioning (DB_VERSIONconst +cleanup_stale_db_files)cache/cache.rsDbValueparams;fetch_cache_rowsported fromrarray+query_mapto a dynamicIN (?,?,...)clausetasks/task_history.rsrarray()→IN (?,?,?),DbValueparamstasks/details.rsbegin/commit_transaction(),DbValueparamstasks/running_tasks_service.rsDbValueparamstelemetry/{mod,service}.rsDbValueparams,DbRowresults.prettierignorecargo-patches/(vendored upstream code)Known caveats
tursois still in pre-release (0.6.0-pre.26). We're now exercising it through the entire e2e suite with the patch applied, but it's worth flagging when reviewing the rollout.tshminitialization race ("Corrupt: shared WAL coordination file is smaller than the coordination header") that's hit ~1 in dozens of runs in tight bursts; CI has not surfaced it but we should add open-time retry in a follow-up if it appears.Related Issue(s)
Supersedes #34933 (the original spike).
Fixes #