forked from surrealdb/surrealdb
-
Notifications
You must be signed in to change notification settings - Fork 0
docs(lance-backend): proven kv-lance feature-gate reference (lite-unified) #47
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
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,158 @@ | ||
| # Lance Feature Gates — the "lite-unified" surreal build | ||
|
|
||
| > **Status:** PROVEN (clean compile). Reference + troubleshooting card. | ||
| > **Branch:** `claude/jirak-math-theorems-harvest-rfii13` | ||
| > **Purpose:** the exact feature-gate invocation that drops the C++/gRPC | ||
| > storage engines and keeps a *pure-Rust columnar* surreal whose backing | ||
| > store is Lance — the substrate a `ractor` actor can subscribe to. | ||
| > | ||
| > This SUPERSEDES the stale `patches/Cargo-toml.patch.txt` (which still | ||
| > describes `kv-lance` as not-yet-wired, `lance = "1.0"`, `arrow = "55"`). | ||
| > The feature is now wired in `surrealdb/core/Cargo.toml`; the pins below | ||
| > are what is actually in tree. | ||
|
|
||
| --- | ||
|
|
||
| ## TL;DR — the one command | ||
|
|
||
| ```bash | ||
| # Lite-unified: pure-Rust columnar surreal, no RocksDB(C++), no TiKV(gRPC). | ||
| cargo build -p surrealdb --no-default-features --features kv-lance,rustls | ||
| # ^^^^^^^^^^^^^^^^^^^^^^ drop protocol-ws default too | ||
| # core-only (no SDK transport surface), fastest troubleshooting loop: | ||
| cargo check -p surrealdb-core --no-default-features --features kv-lance | ||
| ``` | ||
|
|
||
| `--no-default-features` is the load-bearing flag. Without it the | ||
| default set (`kv-mem` on `surrealdb-core`, `protocol-ws,rustls` on the | ||
| `surrealdb` SDK) is *added to* whatever you pass — you would still get a | ||
| clean build but you would NOT have proven that `kv-lance` stands alone. | ||
|
|
||
| **Observed:** clean compile, ~5m43s cold (first build of the lance | ||
| dependency closure), seconds incremental. Zero `cc`/C++ in the closure. | ||
|
|
||
| --- | ||
|
|
||
| ## Why these gates (the lite-unified rationale) | ||
|
|
||
| The 16K mailbox-SoA view runs entirely on lancedb, zero-copy, accessed | ||
| from surreal through the `kv-lance` backend. So the question is never | ||
| "surreal OR lance" — it is "which of surreal's *other* KV engines do we | ||
| drag along." The answer for the lance path: none. | ||
|
|
||
| | Gate | deps it pulls | toolchain | keep in lite? | | ||
| |---|---|---|---| | ||
| | `kv-mem` (core default) | `surrealmx`, `tempfile`, `ext-sort`, `affinitypool` | Rust | optional (tests) | | ||
| | `kv-rocksdb` | `rocksdb` | **C++ (`cc`, libstdc++)** | ❌ drop | | ||
| | `kv-tikv` | `tikv` client | **gRPC / tonic / protoc** | ❌ drop | | ||
| | `kv-surrealkv` | `surrealkv` | Rust | ❌ drop (not lance) | | ||
| | `kv-indxdb` | `indxdb` | WASM-only | ❌ drop | | ||
| | **`kv-lance`** | `lance`, `lance-index`, `lancedb`, `arrow-array`, `arrow-schema` | **pure Rust** | ✅ **keep** | | ||
|
|
||
| Dropping `kv-rocksdb` is what removes the C++ build dependency; dropping | ||
| `kv-tikv` removes the gRPC/protoc requirement. `kv-lance` brings | ||
| arrow-rs + lance + object_store transitively, all Rust. | ||
|
|
||
| --- | ||
|
|
||
| ## The exact pins (ground truth, `surrealdb/core/Cargo.toml`) | ||
|
|
||
| ```toml | ||
| # [features] | ||
| default = ["kv-mem", "graphql"] | ||
| kv-lance = ["dep:lance", "dep:lance-index", "dep:lancedb", | ||
| "dep:arrow-array", "dep:arrow-schema"] | ||
|
|
||
| # the optional "agnostic build first" trait surface (zero-dep): | ||
| lance-graph = ["dep:lance-graph-contract"] | ||
|
|
||
| # [dependencies] — the lance family moves in lockstep (lance-graph PR #445) | ||
| lance = { version = "=7.0.0", optional = true } | ||
| lance-index = { version = "=7.0.0", optional = true } | ||
| lancedb = { version = "=0.30.0", optional = true } | ||
| arrow-array = { version = "58", optional = true } | ||
| arrow-schema= { version = "58", optional = true } | ||
| lance-graph-contract = { workspace = true, optional = true } | ||
| ``` | ||
|
|
||
| ```toml | ||
| # surrealdb/Cargo.toml (SDK crate) — re-export gate | ||
| kv-lance = ["surrealdb-core/kv-lance", "tokio/time"] | ||
| ``` | ||
|
|
||
| **Pin discipline (lance-graph CLAUDE.md P0):** `lance`/`lance-index` are | ||
| exact-pinned `=7.0.0` because `lancedb 0.30.0` transitively requires | ||
| `lance =7.0.0`; `arrow` is `58`. These MUST match the | ||
| `AdaWorldAPI/lance-graph` workspace pin — if lance-graph bumps, this | ||
| backend bumps in lockstep, never independently. Never substitute a | ||
| crates.io lance for a fork build to make a compile pass. | ||
|
|
||
| --- | ||
|
|
||
| ## Troubleshooting matrix | ||
|
|
||
| | Symptom | Cause | Fix | | ||
| |---|---|---| | ||
| | `error: linker cc not found` / libstdc++ link errors | a C++ backend (`kv-rocksdb`) is in the feature set | confirm `--no-default-features`; do not pass `kv-rocksdb` | | ||
| | `failed to run protoc` | `kv-tikv` pulled gRPC | drop `kv-tikv`; lite-unified never needs it | | ||
| | `Patch lance ... was not used in the crate graph` | fork wiring / transitive semver mismatch | check direct `[patch]` + `Cargo.lock`; resolve the transitive blocker, do NOT fall back to crates.io (P0) | | ||
| | `lancedb 0.30 requires lance =7.0.0 but =X found` | lance family drifted out of lockstep | re-pin all three (`lance`, `lance-index`, `lancedb`) to the lance-graph workspace versions together | | ||
| | build "works" but kv-lance never exercised | default features silently re-added `kv-mem` | the proving build MUST use `--no-default-features` | | ||
| | huge first-build time, then fast | cold lance/arrow closure | expected (~5–6 min cold); incremental is seconds | | ||
|
|
||
| --- | ||
|
|
||
| ## The ractor connection (why this card lives next to the ractor fix) | ||
|
|
||
| The lite-unified surreal is the *storage half*; `ractor` is the *actor | ||
| half* of the self-updating substrate. The breakthrough loop: | ||
|
|
||
| ``` | ||
| Lance Dataset::versions() (kv-lance backend, this card) | ||
| │ new version committed | ||
| ▼ | ||
| LanceVersionScheduler (ractor actor, bounded mailbox) | ||
| │ KanbanMove { target: ExecTarget::Jit } | ||
| ▼ | ||
| jitson / Cranelift formula (compute, NOT a query → no DataFusion) | ||
| │ produces a SoA tenant delta | ||
| ▼ | ||
| MailboxSoaView tenant write (zero-copy into the Lance-backed column) | ||
| │ commits a new Lance version ──────► loop closes | ||
| ``` | ||
|
|
||
| - **DataFusion is NOT on this path.** The loop is *compute* (formula | ||
| evaluation), not *query* (SQL planning). `lance`/`lancedb`/`arrow` ARE | ||
| on the path — they are the zero-copy columnar store, not the planner. | ||
| - **Why the ractor messaging fix matters here.** A | ||
| `LanceVersionScheduler` actor that fans `KanbanMove`s to a bounded | ||
| worker mailbox will surface `MessagingErr::Saturated(T)` as graceful | ||
| backpressure (from `try_send` on a full bounded mailbox — distinct | ||
| from `SendErr`, which means the actor is dead). Before the fix, three | ||
| `match` sites in ractor were non-exhaustive on `Saturated` and the | ||
| crate did not compile on default features. Fixed on the same branch | ||
| (`claude/jirak-math-theorems-harvest-rfii13`): | ||
| - receive-side loops (`actor.rs`, `thread_local/inner.rs`): Saturated | ||
| cannot occur receive-side → treat like closed channel (`Signal::Kill`). | ||
| - `derived_actor.rs::get_derived`: deconvert + re-wrap as `Saturated`, | ||
| mirroring the `SendErr` arm — so a `DerivedActorRef` carrying the | ||
| subset `KanbanMove` type propagates backpressure with the typed | ||
| message intact (the scheduler can retry-with-backoff or escalate). | ||
|
|
||
| So: **bounded mailbox + `Saturated` = the backpressure valve** between a | ||
| fast Lance commit stream and a slower jitson compute worker. The lite | ||
| surreal supplies the version stream; ractor supplies the | ||
| ownership-safe, backpressure-aware dispatch. | ||
|
|
||
| --- | ||
|
|
||
| ## What this card does NOT claim | ||
|
|
||
| - Not a benchmark. The 5m43s is a cold-compile wall-clock, not a | ||
| throughput number. Any "faster" claim needs a measured reproducer | ||
| (truth-architect gate). | ||
| - Not a green-light to wire the loop into a real Cargo.toml. The | ||
| `surreal_container` consumer is still `BLOCKED(C)` — the | ||
| `AdaWorldAPI/surrealdb` fork dep (this `kv-lance` feature) is not yet | ||
| added to `surreal_container/Cargo.toml`. That single wiring step + | ||
| the loop above is the remaining work, not a 12-day lift. | ||
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.
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.
For the non-WASM SDK build, this
rustlsfeature is not a pure-Rust/no-ccchoice:surrealdb/Cargo.tomlenablesrustlswithaws_lc_rs, and the checked-in lockfile showsrustlsdepending onaws-lc-rswhileaws-lc-sysdepends onccandcmake. As written, the documented “lite-unified” proof command can still require native build tooling and contradicts the later “Zerocc/C++ in the closure” claim, so users trying to verify a no-native-toolchain Lance-only build can get misleading results; use the core-only command for that proof or document the SDKrustlscaveat.Useful? React with 👍 / 👎.