Make RaindexClient Send+Sync on native targets#2489
Conversation
- Conditionally use async_trait(?Send) for WASM, async_trait for native on LocalDbQueryExecutor trait - Add FnPtr<T> alias (Rc on WASM, Arc on native) for LocalDb internals - Split LocalDb::new into WASM and native impl blocks with correct bounds - Add ClientRef type alias (Rc on WASM, Arc on native) - Gate JsCallbackExecutor module and impl to WASM-only
- Split db/scheduler fields: Rc<RefCell<...>> on WASM, Arc<Mutex<...>> on native - Split LocalDbState::new into per-target impl blocks - Use poison-safe lock access (ok()/if-let) in db(), mark_ready(), is_ready(), and Drop impl
- Replace Rc::new/Rc::clone with ClientRef::new/ClientRef::clone - Update OrdersDataSource, VaultsDataSource traits to use async_trait cfg gate - Update LocalDbOrders, LocalDbVaults to accept ClientRef - Update RaindexOrder, RaindexVault to store ClientRef
- Move clear_tables_wasm into #[cfg(target_family = "wasm")] mod wasm - Move get_sync_status into #[cfg(target_family = "wasm")] mod wasm - Keep core logic functions ungated for both targets
- Apply async_trait cfg gate to all LocalDbQueryExecutor test impls - Replace RefCell with Mutex in test executors - Replace Rc with Arc in test code
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (9)
WalkthroughThis PR introduces comprehensive wasm vs non-wasm target specialization across the local database and raindex client code. Key changes include: conditional async_trait macro application via cfg_attr attributes, introduction of a ClientRef type alias abstracting pointer types (Rc on wasm, Arc on non-wasm), per-target concurrency primitives (RefCell/Mutex), and relocation of wasm-specific exports into cfg-gated modules. Changes
Sequence Diagram(s)[No sequence diagrams generated; changes are primarily architectural refactoring and conditional compilation adjustments affecting trait implementations and ownership models rather than introducing new multi-component interaction flows.] Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Substantial scope spanning 40+ files with heterogeneous changes including: target-specific type abstractions (ClientRef, FnPtr), per-target concurrency primitives (RefCell/Mutex/RwLock), new conditional compilation patterns throughout, public API signature updates in multiple places, and non-trivial architectural decisions for wasm vs non-wasm specialization. Each file cohort requires separate reasoning for correctness of target-specific logic and proper abstraction usage. Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
crates/common/src/raindex_client/local_db/mod.rs (1)
337-340:⚠️ Potential issue | 🔴 CriticalFix WASM test compile failure from missing
RaindexClientimport.Line [391] uses
RaindexClientwithout bringing it into scope, matching the current CI error.
Line [338] also has an unusedTimeoutFutureimport warning.Suggested patch
#[cfg(all(test, target_family = "wasm", feature = "browser-tests"))] mod wasm_tests { use super::*; - use gloo_timers::future::TimeoutFuture; + use crate::raindex_client::RaindexClient; use rain_orderbook_app_settings::spec_version::SpecVersion;Also applies to: 391-393
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/common/src/raindex_client/local_db/mod.rs` around lines 337 - 340, Add a missing import for RaindexClient and remove the unused TimeoutFuture import: bring RaindexClient into scope (e.g., add a use statement referencing RaindexClient so the code that references RaindexClient at lines ~391–393 compiles), and delete the unused use gloo_timers::future::TimeoutFuture; line (or gate it behind a wasm-only cfg if it will be used conditionally) to silence the unused-import warning.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@crates/common/src/raindex_client/local_db/state.rs`:
- Around line 91-96: The code currently swallows poisoned Mutex locks (e.g., in
the db() accessor and the other lock sites referenced) by mapping .lock().ok()
to None/false; instead recover the inner guard from a poisoned lock so local DB
routing and cleanup remain deterministic. Replace .lock().ok().and_then(|guard|
guard.as_ref().cloned()) with lock handling that matches on self.db.lock(): on
Ok(guard) use guard.as_ref().cloned(); on Err(poisoned) call
poisoned.into_inner() and then guard.as_ref().cloned(); apply the same pattern
to the other mutex accesses (the places around the other boolean/guard checks in
the file) so that poison does not silently fall back to subgraph or skip
scheduler stop. Ensure the logic still clones/returns LocalDb (or boolean) as
before after recovering the inner guard.
---
Outside diff comments:
In `@crates/common/src/raindex_client/local_db/mod.rs`:
- Around line 337-340: Add a missing import for RaindexClient and remove the
unused TimeoutFuture import: bring RaindexClient into scope (e.g., add a use
statement referencing RaindexClient so the code that references RaindexClient at
lines ~391–393 compiles), and delete the unused use
gloo_timers::future::TimeoutFuture; line (or gate it behind a wasm-only cfg if
it will be used conditionally) to silence the unused-import warning.
ℹ️ Review info
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (26)
crates/cli/src/commands/local_db/pipeline/bootstrap.rscrates/common/src/local_db/executor.rscrates/common/src/local_db/export.rscrates/common/src/local_db/pipeline/adapters/apply.rscrates/common/src/local_db/pipeline/adapters/bootstrap.rscrates/common/src/local_db/pipeline/adapters/tokens.rscrates/common/src/local_db/pipeline/adapters/window.rscrates/common/src/local_db/pipeline/engine.rscrates/common/src/local_db/query/executor.rscrates/common/src/raindex_client/add_orders.rscrates/common/src/raindex_client/local_db/executor.rscrates/common/src/raindex_client/local_db/mod.rscrates/common/src/raindex_client/local_db/orders.rscrates/common/src/raindex_client/local_db/pipeline/bootstrap.rscrates/common/src/raindex_client/local_db/pipeline/runner/mod.rscrates/common/src/raindex_client/local_db/pipeline/runner/scheduler/native.rscrates/common/src/raindex_client/local_db/query/clear_tables.rscrates/common/src/raindex_client/local_db/query/fetch_last_synced_block.rscrates/common/src/raindex_client/local_db/state.rscrates/common/src/raindex_client/local_db/vaults.rscrates/common/src/raindex_client/mod.rscrates/common/src/raindex_client/orders.rscrates/common/src/raindex_client/remove_orders.rscrates/common/src/raindex_client/trades.rscrates/common/src/raindex_client/vaults.rscrates/js_api/src/registry.rs
Replace .ok() / unwrap_or(false) lock handling with into_inner() so that a poisoned Mutex/RwLock returns the correct value rather than falling back to subgraph or skipping scheduler cleanup.
The wasm_tests module used RaindexClient without importing it, causing a build failure under the browser-tests feature flag.
Resolve conflicts from merging 2026-03-03-raindex-client-localdb-refactor: - Combine 3-arg RaindexClient::new() signature with Arc<Mutex> wrappers - Keep native Arc<Mutex> scheduler initialization - Remove unused RaindexClient import in local_db/mod.rs - Remove duplicate get_raindex_client_native in favor of upstream get_raindex_client
|
@coderabbitai assess this PR size classification for the totality of the PR with the following criterias and report it in your comment: S/M/L PR Classification Guidelines:This guide helps classify merged pull requests by effort and complexity rather than just line count. The goal is to assess the difficulty and scope of changes after they have been completed. Small (S)Characteristics:
Review Effort: Would have taken 5-10 minutes Examples:
Medium (M)Characteristics:
Review Effort: Would have taken 15-30 minutes Examples:
Large (L)Characteristics:
Review Effort: Would have taken 45+ minutes Examples:
Additional Factors to ConsiderWhen deciding between sizes, also consider:
Notes:
|
|
Tip For best results, initiate chat on the files or code changes. SIZE=L 🧠 Learnings used |
Dependent PRs
Motivation
Following the local DB refactor in #2488,
RaindexClientand its dependency graph (LocalDb,LocalDbState,LocalDbQueryExecutor) still usedRc/RefCelleverywhere, making them!Send + !Syncon native targets. This blocks usingRaindexClientacross threads in CLI/server contexts.Solution
1.
LocalDbQueryExecutortrait — conditionalSendboundThe trait now uses
async_trait(?Send)on WASM andasync_trait(withSend) on native, via#[cfg_attr].2.
LocalDb—Arc-based internals on nativeFnPtr<T>alias:Rc<T>on WASM,Arc<T>on nativeExecuteBatchFn, etc.) requireSend + Syncon nativeimpl LocalDbblocks with platform-appropriate bounds3.
LocalDbState— thread-safe fields on nativedbfield:Rc<RefCell<...>>on WASM,Arc<Mutex<...>>on nativeschedulerfield: same split.ok(),if let Ok(...),.unwrap_or(false))4.
ClientReftype aliasRc<RaindexClient>on WASM,Arc<RaindexClient>on nativeorders,vaults,trades,add_orders,remove_orders)5. WASM export isolation
clear_tables_wasmandget_sync_statusmoved into#[cfg(target_family = "wasm")] mod wasmblocksJsCallbackExecutormodule gated to WASM-only6. Test updates
LocalDbQueryExecutormock impls updated withasync_traitcfg gateRefCell→Mutex,Rc→Arcin test codeChecks
By submitting this for review, I'm confirming I've done the following:
Summary by CodeRabbit