-
Notifications
You must be signed in to change notification settings - Fork 21
Switch SurrealDB from In-Memory to File-Based RocksDB Storage #652
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
Show all changes
26 commits
Select commit
Hold shift + click to select a range
e376c1d
Surreal files per perspective wip 1
lucksus 35275ce
Avoid duplicate links w/ unique index and handle lock and write errors
lucksus 6d90f2f
Fix new remove_link on surreal service
lucksus 053c5dc
Rename update_surreal_cache() to persist_link_diff()
lucksus 19abd3b
Temporary perspective data migration from rusqlite to surreal
lucksus 48d1ef2
fmt
lucksus 818d756
fix: address CodeRabbit issues #2, #3, #7
data-coasys 6aecb22
fix: preserve original link status instead of hardcoding Local (issue…
data-coasys 8c65f6c
fix: propagate SurrealDB write failures to prevent desync (issue #1)
data-coasys a9e43af
fix: honor full unique constraint in SurrealDB lookups (issue #6)
data-coasys fa3c173
fix: prevent TOCTOU race in initialize_from_db (issue #5)
data-coasys c79a924
fix: clone link.status to avoid partial move
data-coasys 640b6e6
fix: borrow links in migration loop to avoid partial move
data-coasys 5b76446
chore: run cargo fmt and add PR fixes summary
data-coasys cbc752d
refactor: remove redundant variable reassignments in get_link
data-coasys 8292044
fix: address CodeRabbit feedback on PR #652
data-coasys fa4382f
reset bootstrapSeed.json
lucksus ee1143d
Handle fallback sync read failure gracefully.
lucksus 9e8e5b4
Don’t proceed when migration fails.
lucksus e57b8f8
Fix inconsistent error handling: .expect() vs. map_err()?
lucksus ce4c6c0
fix: handle SurrealDB service creation failure in initialize_from_db
data-coasys 6b34334
Merge branch 'dev' into surreal-files
lucksus 0da45d7
Merge branch 'dev' into surreal-files
lucksus 3931d7c
don't fail silently if links from DB can't be parsed
lucksus 2e0aef8
don't panic on DB write failures but log error
lucksus 942e2d4
Merge branch 'dev' into surreal-files
lucksus 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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| # CodeRabbit PR #652 Fix Tasks | ||
|
|
||
| ## Critical Issues | ||
|
|
||
| ### 1. perspective_instance.rs (lines 2425-2457) | ||
| **Issue**: `persist_link_diff` and `retry_surreal_op` silently swallow errors, risking desync. | ||
| **Fix**: Make both return `Result` and propagate failures to callers. | ||
|
|
||
| ```rust | ||
| // Change retry_surreal_op signature to return Result | ||
| async fn retry_surreal_op<F, Fut>( | ||
| op: F, | ||
| uuid: &str, | ||
| op_name: &str, | ||
| ) -> Result<(), anyhow::Error> | ||
|
|
||
| // Change persist_link_diff signature to return Result | ||
| pub(crate) async fn persist_link_diff( | ||
| &self, | ||
| diff: &DecoratedPerspectiveDiff, | ||
| ) -> Result<(), AnyError> | ||
|
|
||
| // Update callsites: | ||
| // - Functions returning Result: change `.await;` to `.await?;` | ||
| // - diff_from_link_language: use `.await.expect("SurrealDB link persistence failed");` | ||
| ``` | ||
|
|
||
| ### 2. MIGRATION_REMOVAL_GUIDE.md (line 112-113) | ||
| **Issue**: Incomplete sentence in heading. | ||
| **Fix**: Change "Can optionally be cleaned up:" to "The following can optionally be cleaned up:" | ||
|
|
||
| ### 3. migration.rs (lines 97-119) | ||
| **Issue**: Marks perspective as migrated even when some links failed, risking data loss. | ||
| **Fix**: Only mark as migrated when `error_count == 0`, otherwise return error. | ||
|
|
||
| ### 4. mod.rs (lines 441-457) | ||
| **Issue**: Hardcodes `LinkStatus::Local` instead of preserving original status. | ||
| **Fix**: Read `link.status` and use it (fallback to `LinkStatus::Local` if None). | ||
|
|
||
| ### 5. mod.rs (lines 56-66) | ||
| **Issue**: TOCTOU race in `initialize_from_db` - multiple tasks can create duplicate SurrealDB services. | ||
| **Fix**: Use atomic entry-or-init pattern with write lock to prevent duplicates. | ||
|
|
||
| ### 6. perspective_instance.rs (lines 878-891) | ||
| **Issue**: SurrealDB lookup only uses (source, target, predicate) instead of full unique constraint. | ||
| **Fix**: Include author and timestamp in lookups to honor all 5 fields of link_unique_idx. | ||
|
|
||
| ### 7. surreal_service/mod.rs (lines 532-576) | ||
| **Issue**: Overly broad error handling treats any "index" error as benign. | ||
| **Fix**: Only check for "unique", "duplicate", "already exists" - remove "index" check. | ||
|
|
||
| ## Nitpicks | ||
|
|
||
| ### 8. mod.rs (lines 80-93) | ||
| **Note**: Migration failures logged at error level but user won't see in UI. | ||
| Consider adding visible notification mechanism for production. | ||
|
|
||
| ### 9. surreal_service/mod.rs (lines 756-904) | ||
| **Note**: DRY the repeated SurrealLink deserialization pattern across getters. | ||
| Consider extracting helper function. | ||
|
|
||
| --- | ||
|
|
||
| ## Execution Plan | ||
|
|
||
| 1. Fix critical issues 1-7 first | ||
| 2. Address nitpicks 8-9 if time permits | ||
| 3. Run cargo fmt | ||
| 4. Commit and push to `surreal-files` branch | ||
| 5. Wait for CodeRabbit re-analysis |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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,57 @@ | ||
| # PR #652 CodeRabbit Fixes - Summary | ||
|
|
||
| ## All 7 Actionable Issues Fixed ✅ | ||
|
|
||
| ### Issue #1: Error Propagation (perspective_instance.rs lines 2425-2457) | ||
| **Problem**: `persist_link_diff` and `retry_surreal_op` silently swallowed errors | ||
| **Fix**: | ||
| - Changed both functions to return `Result<(), AnyError>` | ||
| - Updated all callsites to propagate errors using `?` or `.expect()` | ||
| - Functions returning `()` use `.expect()` to fail-fast | ||
| - Functions returning `Result` use `?` to propagate | ||
|
|
||
| ### Issue #2: Documentation (MIGRATION_REMOVAL_GUIDE.md line 112-113) | ||
| **Problem**: Incomplete sentence in heading | ||
| **Fix**: Changed "Can optionally be cleaned up:" to "The following can optionally be cleaned up:" | ||
|
|
||
| ### Issue #3: Migration Safety (migration.rs lines 97-119) | ||
| **Problem**: Marked perspective as migrated even when errors occurred | ||
| **Fix**: Only mark as migrated when `error_count == 0`, otherwise return error | ||
|
|
||
| ### Issue #4: Link Status Preservation (mod.rs lines 441-457) | ||
| **Problem**: Hardcoded `LinkStatus::Local` instead of preserving original | ||
| **Fix**: Read `link.status` and use it (fallback to `LinkStatus::Local` if None) | ||
|
|
||
| ### Issue #5: TOCTOU Race (mod.rs lines 56-66) | ||
| **Problem**: Race condition in `initialize_from_db` allowing duplicate SurrealDB services | ||
| **Fix**: Added atomic check-and-insert after async initialization completes | ||
|
|
||
| ### Issue #6: Unique Constraint (perspective_instance.rs lines 878-891) | ||
| **Problem**: SurrealDB lookups only used 3 fields instead of full unique constraint (5 fields) | ||
| **Fix**: | ||
| - Updated `get_link` to accept optional `author` and `timestamp` | ||
| - When provided, queries using all 5 fields: source, target, predicate, author, timestamp | ||
| - All callsites updated to pass author and timestamp from LinkExpression | ||
|
|
||
| ### Issue #7: Error Handling (surreal_service/mod.rs lines 532-576) | ||
| **Problem**: Overly broad error check treated any "index" error as benign | ||
| **Fix**: Removed "index" check, only checks for "unique", "duplicate", and "already exists" | ||
|
|
||
| ## Additional Compilation Fixes | ||
| - Fixed partial move error in `import_perspective` (clone link.status) | ||
| - Fixed partial move error in migration loop (borrow &links instead of consuming) | ||
|
|
||
| ## Commits | ||
| 1. `818d756e` - Issues #2, #3, #7 + docstrings | ||
| 2. `6aecb225` - Issue #4 (preserve link status) | ||
| 3. `8c65f6c7` - Issue #1 (error propagation) | ||
| 4. `a9e43aff` - Issue #6 (unique constraint) | ||
| 5. `fa3c1734` - Issue #5 (TOCTOU race) | ||
| 6. `c79a9244` - Fix partial move (link.status) | ||
| 7. `640b6e65` - Fix partial move (migration loop) | ||
|
|
||
| ## Status | ||
| - ✅ All CodeRabbit actionable comments addressed | ||
| - ✅ Additional docstrings added for coverage | ||
| - 🔄 Building rust-executor to verify compilation | ||
| - ⏳ Next: cargo fmt, run full test suite |
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,113 @@ | ||
| # Migration Removal Guide | ||
|
|
||
| This document explains how to remove the one-time Rusqlite-to-SurrealDB migration code after all users have migrated. | ||
|
|
||
| ## When to Remove | ||
|
|
||
| Remove this migration code in a future version (e.g., version 0.13.0 or later) after confirming: | ||
| - All active users have upgraded to version 0.11.2 or later | ||
| - Sufficient time has passed for users to run the migration (recommend at least 2-3 releases) | ||
| - No support requests related to missing links after migration | ||
|
|
||
| ## Removal Steps | ||
|
|
||
| ### 1. Delete the Migration Module | ||
| ```bash | ||
| rm src/perspectives/migration.rs | ||
| ``` | ||
|
|
||
| ### 2. Update src/perspectives/mod.rs | ||
|
|
||
| Remove the migration module declaration: | ||
| ```rust | ||
| // Remove this line: | ||
| pub mod migration; // TODO: Remove this module after all users have migrated to SurrealDB | ||
| ``` | ||
|
|
||
| Remove migration calls from `initialize_from_db()`: | ||
| ```rust | ||
| // Remove these lines (around line 74-78): | ||
| // Migrate links from Rusqlite to SurrealDB (one-time migration) | ||
| // TODO: Remove this migration call after all users have migrated | ||
| if let Err(e) = migration::migrate_links_from_rusqlite_to_surrealdb(&handle_clone.uuid, &surreal_service).await { | ||
| log::error!("Failed to migrate links for perspective {}: {}", handle_clone.uuid, e); | ||
| } | ||
| ``` | ||
|
|
||
| Remove migration calls from `add_perspective()`: | ||
| ```rust | ||
| // Remove these lines (around line 119-123): | ||
| // Migrate links from Rusqlite to SurrealDB (one-time migration) | ||
| // TODO: Remove this migration call after all users have migrated | ||
| if let Err(e) = migration::migrate_links_from_rusqlite_to_surrealdb(&handle.uuid, &surreal_service).await { | ||
| log::error!("Failed to migrate links for perspective {}: {}", handle.uuid, e); | ||
| } | ||
| ``` | ||
|
|
||
| ### 3. (Optional) Clean Up Database Migration Support | ||
|
|
||
| If you want to completely remove migration infrastructure from src/db.rs: | ||
|
|
||
| Remove the migration tracking table from `new()`: | ||
| ```rust | ||
| // Remove these lines (around line 158-165): | ||
| conn.execute( | ||
| "CREATE TABLE IF NOT EXISTS perspective_link_migration ( | ||
| id INTEGER PRIMARY KEY, | ||
| perspective_uuid TEXT NOT NULL UNIQUE, | ||
| migrated_at TEXT NOT NULL | ||
| )", | ||
| [], | ||
| )?; | ||
| ``` | ||
|
|
||
| Remove migration methods: | ||
| ```rust | ||
| // Remove these methods: | ||
| - pub fn is_perspective_migrated(&self, perspective_uuid: &str) -> Ad4mDbResult<bool> | ||
| - pub fn mark_perspective_as_migrated(&self, perspective_uuid: &str) -> Ad4mDbResult<()> | ||
| - pub fn delete_all_links_for_perspective(&self, perspective_uuid: &str) -> Ad4mDbResult<usize> | ||
| ``` | ||
|
|
||
| **Note:** Keeping these methods is harmless and may be useful for future migrations, so removal is optional. | ||
|
|
||
| ### 4. Verify Removal | ||
|
|
||
| After removing the migration code: | ||
|
|
||
| 1. **Build the project:** | ||
| ```bash | ||
| cargo build --lib | ||
| ``` | ||
|
|
||
| 2. **Run tests:** | ||
| ```bash | ||
| cargo test --lib | ||
| ``` | ||
|
|
||
| 3. **Verify no references remain:** | ||
| ```bash | ||
| grep -r "migrate_links_from_rusqlite_to_surrealdb" rust-executor/src/ | ||
| grep -r "migration::" rust-executor/src/perspectives/mod.rs | ||
| ``` | ||
| Both should return no results. | ||
|
|
||
| ## Migration Summary | ||
|
|
||
| ### What the Migration Did | ||
| - Moved all link data from the centralized Rusqlite database to per-perspective SurrealDB databases | ||
| - Preserved all link metadata (author, timestamp, proof, status) | ||
| - Ensured idempotent operation (safe to run multiple times) | ||
| - Cleaned up old link data from Rusqlite after successful migration | ||
| - Tracked migration status per perspective to prevent repeated migrations | ||
|
|
||
| ### Files Affected by Migration | ||
|
|
||
| **Will be removed:** | ||
| - `src/perspectives/migration.rs` - The migration logic and tests | ||
|
|
||
| **Will be updated:** | ||
| - `src/perspectives/mod.rs` - Remove module declaration and migration calls | ||
|
|
||
| **The following can optionally be cleaned up:** | ||
| - `src/db.rs` - Migration tracking methods (optional to remove) |
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
Oops, something went wrong.
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.
🧩 Analysis chain
🌐 Web query:
SurrealDB 2.4 kv-rocksdb feature RocksDB build requirements💡 Result:
For SurrealDB 2.4.x, enabling the RocksDB storage engine is done via the Cargo feature
kv-rocksdb(e.g.cargo build --features surrealdb/kv-rocksdb). [1]What you need installed to build with
kv-rocksdbBecause this feature compiles native RocksDB bindings, you generally need:
LIBCLANG_PATH/LLVM_CONFIG_PATHif autodetection fails (common when compilinglibrocksdb-sys). [6]llvm-configat build time and linking againstlibrocksdb(and oftenzstd). [2]Optional / common native deps
Notes
Sources: SurrealDB blog/docs and crate docs for enabling
kv-rocksdband bindgen/libclang requirements, plus RocksDB install notes and packaging metadata. [1][2][3][4][5][6]🌐 Web query:
SurrealDB cargo features kv-rocksdb kv-mem scripting compatibility 2.4💡 Result:
For SurrealDB Rust crates in the 2.4.x line, the Cargo feature flags you mentioned are present and compatible:
kv-mem: in-memory storage engine (and it’s the default forsurrealdb-core 2.4.1). (docs.rs)kv-rocksdb: RocksDB-backed storage engine. (Enabling embedded engines requires turning on the correspondingkv-*feature; RocksDB also brings native build deps.) (docs.rs)scripting: enables SurrealDB’s scripting support (wired to ajsdependency insurrealdb-core). (docs.rs)In the top-level
surrealdbcrate, these features map through tosurrealdb-core(e.g.,scripting = ["surrealdb-core/scripting"],kv-rocksdb = ["surrealdb-core/kv-rocksdb", ...]). (docs.rs)Example
Cargo.toml(2.4.x) enabling all three:Citations:
Ensure CI has C/C++ compiler and LLVM/clang for building with
kv-rocksdb.The feature combination is supported in SurrealDB 2.4, but enabling
kv-rocksdbrequires native build dependencies: a C++11-capable C/C++ compiler and LLVM/clang (for bindgen to compile RocksDB bindings). Verify that CI runners and local build environments have these toolchains available; you may also need to setLIBCLANG_PATHorLLVM_CONFIG_PATHif autodetection fails.🤖 Prompt for AI Agents