-
Notifications
You must be signed in to change notification settings - Fork 13
Implement per-network independent sync cycles for Local DB #2380
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
base: main
Are you sure you want to change the base?
Conversation
- Each network runs in its own independent loop
- Per-network Web Locks: "local-db-sync-engine-{network_key}"
- Schema init runs once before spawning network loops
- Add RunOutcome enum (Report/NotLeader)
- Add NetworkSyncStatus for per-network status reporting
- Syncing status only emitted after confirmed leadership
- Fire-and-forget stop (sync, not async)
- Add integration test for slow network independence
- Change to map-based networkStatuses store - Add updateNetworkStatus() helper - Add aggregateStatus derived store (failure > syncing > active) - Update +layout.svelte to use new callback - Fix Sidebar tests for new store API
WalkthroughImplements per-network independent Local DB sync loops and per-network status reporting. Adds Changes
Sequence Diagram(s)sequenceDiagram
participant Scheduler as Scheduler
participant NetLoop as Per-Network Loop
participant Runner as ClientRunner
participant Leadership as Leadership
participant DB as LocalDb
participant UI as Webapp Store
rect rgb(200,220,240)
note over Scheduler: startup
Scheduler->>Scheduler: parse global settings & build NetworkRunnerConfig per network
Scheduler->>DB: initialize DB schema (once)
end
rect rgb(220,240,220)
note over NetLoop: independent per-network cycle
loop per-network sync
NetLoop->>Runner: instantiate runner for network
Runner->>Leadership: attempt acquire leadership (network lock)
alt acquired
Leadership-->>Runner: Leader
Runner->>DB: fetch manifests & provision dumps
Runner->>DB: execute sync cycle
Runner-->>NetLoop: RunOutcome::Report(RunReport)
else not leader
Leadership-->>Runner: NotLeader
Runner-->>NetLoop: RunOutcome::NotLeader
end
NetLoop->>UI: emit NetworkSyncStatus(networkKey, chainId, status, schedulerState, error?)
NetLoop->>NetLoop: sleep until next scheduled cycle
end
end
rect rgb(240,220,200)
note over Scheduler: stop
Scheduler->>NetLoop: stop all per-network loops (sync)
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (3)crates/**/*.rs📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
**/crates/**📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.rs📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (5)📓 Common learnings📚 Learning: 2025-10-14T07:51:55.148ZApplied to files:
📚 Learning: 2025-10-06T14:41:41.909ZApplied to files:
📚 Learning: 2025-12-03T10:40:25.429ZApplied to files:
📚 Learning: 2025-10-06T11:13:29.956ZApplied to files:
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
🔇 Additional comments (7)
Comment |
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.
Actionable comments posted: 2
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (9)
crates/common/src/local_db/pipeline/runner/mod.rscrates/common/src/raindex_client/local_db/mod.rscrates/common/src/raindex_client/local_db/pipeline/runner/config.rscrates/common/src/raindex_client/local_db/pipeline/runner/leadership.rscrates/common/src/raindex_client/local_db/pipeline/runner/mod.rscrates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rspackages/webapp/src/__tests__/Sidebar.test.tspackages/webapp/src/lib/stores/localDbStatus.tspackages/webapp/src/routes/+layout.svelte
🧰 Additional context used
📓 Path-based instructions (10)
crates/**/*.rs
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
crates/**/*.rs: For Rust crates incrates/*, run lints usingnix develop -c cargo clippy --workspace --all-targets --all-features -D warnings
For Rust crates incrates/*, run tests usingnix develop -c cargo test --workspaceor--package <crate>
Files:
crates/common/src/local_db/pipeline/runner/mod.rscrates/common/src/raindex_client/local_db/pipeline/runner/config.rscrates/common/src/raindex_client/local_db/pipeline/runner/leadership.rscrates/common/src/raindex_client/local_db/pipeline/runner/mod.rscrates/common/src/raindex_client/local_db/mod.rscrates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
**/crates/**
📄 CodeRabbit inference engine (AGENTS.md)
Rust workspace organized as
crates/*with subdirectories: cli, common, bindings, js_api, quote, subgraph, settings, math, integration_tests
Files:
crates/common/src/local_db/pipeline/runner/mod.rscrates/common/src/raindex_client/local_db/pipeline/runner/config.rscrates/common/src/raindex_client/local_db/pipeline/runner/leadership.rscrates/common/src/raindex_client/local_db/pipeline/runner/mod.rscrates/common/src/raindex_client/local_db/mod.rscrates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
**/*.rs
📄 CodeRabbit inference engine (AGENTS.md)
**/*.rs: Rust: format code withnix develop -c cargo fmt --all
Rust: lint withnix develop -c rainix-rs-static(preconfigured flags included)
Rust: crates and modules usesnake_case; types usePascalCase
Files:
crates/common/src/local_db/pipeline/runner/mod.rscrates/common/src/raindex_client/local_db/pipeline/runner/config.rscrates/common/src/raindex_client/local_db/pipeline/runner/leadership.rscrates/common/src/raindex_client/local_db/pipeline/runner/mod.rscrates/common/src/raindex_client/local_db/mod.rscrates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
packages/webapp/**/*.{svelte,ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
For Webapp (
packages/webapp), run lints and format checks usingnix develop -c npm run svelte-lint-format-check -w @rainlanguage/webapp
Files:
packages/webapp/src/lib/stores/localDbStatus.tspackages/webapp/src/routes/+layout.sveltepackages/webapp/src/__tests__/Sidebar.test.ts
packages/webapp/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
For Webapp (
packages/webapp), run tests usingnix develop -c npm run test -w @rainlanguage/webapp
Files:
packages/webapp/src/lib/stores/localDbStatus.tspackages/webapp/src/__tests__/Sidebar.test.ts
packages/{webapp,ui-components}/**/*.{svelte,ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
If you modify frontend code or functionality affecting the frontend, you MUST provide a screenshot of the built webapp reflecting your change.
Files:
packages/webapp/src/lib/stores/localDbStatus.tspackages/webapp/src/routes/+layout.sveltepackages/webapp/src/__tests__/Sidebar.test.ts
packages/**/*.{js,ts,svelte}
📄 CodeRabbit inference engine (AGENTS.md)
JavaScript/Svelte organized as
packages/*including webapp, ui-components, and orderbook (wasm wrapper published to npm)
Files:
packages/webapp/src/lib/stores/localDbStatus.tspackages/webapp/src/routes/+layout.sveltepackages/webapp/src/__tests__/Sidebar.test.ts
**/*.{ts,tsx,svelte}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,svelte}: TypeScript/Svelte: format withnix develop -c npm run format
TypeScript/Svelte: lint withnix develop -c npm run lint
TypeScript/Svelte: type-check withnix develop -c npm run check
Files:
packages/webapp/src/lib/stores/localDbStatus.tspackages/webapp/src/routes/+layout.sveltepackages/webapp/src/__tests__/Sidebar.test.ts
**/*.svelte
📄 CodeRabbit inference engine (AGENTS.md)
Svelte components should use
PascalCase.sveltenaming convention; other files use kebab or snake case as appropriate
Files:
packages/webapp/src/routes/+layout.svelte
**/*.{test,spec}.ts
📄 CodeRabbit inference engine (AGENTS.md)
TypeScript/Svelte: run tests with
nix develop -c npm run test(Vitest). Name test files*.test.tsor*.spec.ts
Files:
packages/webapp/src/__tests__/Sidebar.test.ts
🧠 Learnings (35)
📓 Common learnings
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2202
File: crates/common/src/raindex_client/local_db/sync.rs:33-34
Timestamp: 2025-10-14T07:51:55.148Z
Learning: In `crates/common/src/raindex_client/local_db/sync.rs`, the hard-coded `DEFAULT_SYNC_CHAIN_ID` constant (set to `SUPPORTED_LOCAL_DB_CHAINS[0]`) will be replaced with proper chain ID handling in downstream PRs as part of the multi-network/orderbook implementation.
📚 Learning: 2025-12-03T10:40:25.429Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2344
File: crates/common/src/local_db/pipeline/runner/mod.rs:18-31
Timestamp: 2025-12-03T10:40:25.429Z
Learning: In `crates/common/src/local_db/pipeline/runner/mod.rs`, the `TargetSuccess` struct does not need separate `ob_id` or `orderbook_key` fields because the contained `SyncOutcome` already includes orderbook identification information such as chain_id and orderbook_address. This avoids redundant data duplication.
Applied to files:
crates/common/src/local_db/pipeline/runner/mod.rscrates/common/src/raindex_client/local_db/pipeline/runner/config.rscrates/common/src/raindex_client/local_db/pipeline/runner/mod.rscrates/common/src/raindex_client/local_db/mod.rscrates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
📚 Learning: 2025-04-03T09:45:04.200Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1477
File: crates/settings/src/remote_networks.rs:40-75
Timestamp: 2025-04-03T09:45:04.200Z
Learning: The RemoteNetworksCfg implementation in crates/settings/src/remote_networks.rs intentionally fetches remote networks sequentially rather than in parallel.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/config.rscrates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
📚 Learning: 2025-06-18T19:24:40.518Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1938
File: crates/settings/src/yaml/orderbook.rs:185-199
Timestamp: 2025-06-18T19:24:40.518Z
Learning: In crates/settings/src/yaml/orderbook.rs, the user prefers not to refactor get_orderbook_by_network_key to handle multiple orderbooks per network key since their current architecture maintains a one-to-one mapping between orderbooks and networks. They would consider the refactoring if the system evolves to support multiple orderbooks per network in the future.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/config.rs
📚 Learning: 2025-06-10T12:04:54.107Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1916
File: packages/ui-components/src/lib/__fixtures__/settings-12-11-24.json:182-195
Timestamp: 2025-06-10T12:04:54.107Z
Learning: In test fixture files like `packages/ui-components/src/lib/__fixtures__/settings-12-11-24.json`, network configuration inconsistencies (such as matchain using Polygon's RPC, chainId, and currency while having its own network key) are acceptable since they are used for testing purposes only.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/config.rspackages/webapp/src/__tests__/Sidebar.test.ts
📚 Learning: 2025-06-10T12:08:23.128Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1916
File: packages/webapp/src/lib/services/resetActiveNetworkRef.ts:18-20
Timestamp: 2025-06-10T12:08:23.128Z
Learning: In the new NewConfig system that replaced ConfigSource in the rain.orderbook project, the settings store guarantees that $settings.orderbook.networks (and similar nested fields) will always be defined, so null/undefined safety checks are not needed when accessing these fields.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/config.rs
📚 Learning: 2025-10-18T10:38:41.273Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2237
File: crates/common/src/raindex_client/local_db/sync.rs:79-89
Timestamp: 2025-10-18T10:38:41.273Z
Learning: In `crates/common/src/raindex_client/local_db/sync.rs`, the sync_database method currently only supports indexing a single orderbook per chain ID, which is why `.first()` is used to select the orderbook configuration. Multi-orderbook support per chain ID is planned for future PRs.
Applied to files:
packages/webapp/src/lib/stores/localDbStatus.tscrates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
📚 Learning: 2025-10-14T07:51:55.148Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2202
File: crates/common/src/raindex_client/local_db/sync.rs:33-34
Timestamp: 2025-10-14T07:51:55.148Z
Learning: In `crates/common/src/raindex_client/local_db/sync.rs`, the hard-coded `DEFAULT_SYNC_CHAIN_ID` constant (set to `SUPPORTED_LOCAL_DB_CHAINS[0]`) will be replaced with proper chain ID handling in downstream PRs as part of the multi-network/orderbook implementation.
Applied to files:
packages/webapp/src/lib/stores/localDbStatus.tscrates/common/src/raindex_client/local_db/pipeline/runner/leadership.rscrates/common/src/raindex_client/local_db/pipeline/runner/mod.rscrates/common/src/raindex_client/local_db/mod.rscrates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
📚 Learning: 2025-10-29T13:29:29.578Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2278
File: packages/webapp/src/lib/services/startLocalDbSync.ts:23-29
Timestamp: 2025-10-29T13:29:29.578Z
Learning: In packages/webapp/src/lib/services/startLocalDbSync.ts, the hard-coded default orderbook address '0x2f209e5b67A33B8fE96E28f24628dF6Da301c8eB' is a temporary placeholder that will be removed when new sync logic is introduced in the Raindex client, as documented in the NOTE comment.
Applied to files:
packages/webapp/src/lib/stores/localDbStatus.tspackages/webapp/src/routes/+layout.svelte
📚 Learning: 2025-06-11T11:27:14.391Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1917
File: tauri-app/src/lib/stores/order.ts:10-15
Timestamp: 2025-06-11T11:27:14.391Z
Learning: In this codebase, Svelte writable/derived stores (e.g., `subgraph` in `tauri-app/src/lib/stores/settings.ts`) expose a custom asynchronous `.load()` helper that retrieves the current value, so calls like `await subgraph.load()` are valid.
Applied to files:
packages/webapp/src/lib/stores/localDbStatus.ts
📚 Learning: 2025-06-11T11:22:24.903Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1917
File: tauri-app/src/routes/orders/[network]-[orderHash]/+page.svelte:26-37
Timestamp: 2025-06-11T11:22:24.903Z
Learning: In the tauri-app codebase, the `settings` Svelte store is always initialized with a complete `Config` object whose `orderbook` field (and nested maps such as `orderbooks`, `subgraphs`, and `networks`) is guaranteed to exist, so optional chaining on those paths is unnecessary.
Applied to files:
packages/webapp/src/lib/stores/localDbStatus.ts
📚 Learning: 2025-05-19T17:16:54.732Z
Learnt from: hardingjam
Repo: rainlanguage/rain.orderbook PR: 1831
File: packages/ui-components/src/__tests__/transactionStore.test.ts:3-5
Timestamp: 2025-05-19T17:16:54.732Z
Learning: In the rain.orderbook project, there is an ongoing migration of transaction handling from the legacy transactionStore to a new TransactionManager. TransactionStatusMessage has been moved to lib/types/transaction.ts, while TransactionErrorMessage is still in transactionStore but will be moved once other transactions are migrated.
Applied to files:
packages/webapp/src/lib/stores/localDbStatus.ts
📚 Learning: 2025-10-06T10:23:57.479Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2111
File: packages/webapp/src/routes/db-playground/+page.svelte:149-153
Timestamp: 2025-10-06T10:23:57.479Z
Learning: The db-playground page at packages/webapp/src/routes/db-playground/+page.svelte is used for testing purposes, and production-level concerns (such as invalid RPC tokens) are acceptable in this context.
Applied to files:
packages/webapp/src/routes/+layout.svelte
📚 Learning: 2025-03-31T10:16:53.544Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1469
File: packages/ui-components/src/__tests__/CodeMirrorDotrain.test.ts:75-98
Timestamp: 2025-03-31T10:16:53.544Z
Learning: In the rainlanguage/rain.orderbook project, direct manipulation of Svelte's internal state (component.$$.ctx) in tests is an acceptable approach for testing component behavior, as demonstrated in the CodeMirrorDotrain tests.
Applied to files:
packages/webapp/src/routes/+layout.sveltepackages/webapp/src/__tests__/Sidebar.test.ts
📚 Learning: 2025-04-08T12:53:12.526Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1588
File: packages/orderbook/test/js_api/gui.test.ts:2037-2057
Timestamp: 2025-04-08T12:53:12.526Z
Learning: In the remote network test for gui.test.ts, asserting that getCurrentDeployment() succeeds is sufficient validation that remote networks were properly fetched, as this operation would fail if the networks weren't correctly processed.
Applied to files:
packages/webapp/src/__tests__/Sidebar.test.ts
📚 Learning: 2025-09-02T08:04:44.814Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2117
File: packages/ui-components/src/__tests__/VaultIdInformation.test.ts:9-13
Timestamp: 2025-09-02T08:04:44.814Z
Learning: In packages/ui-components/src/__tests__/VaultIdInformation.test.ts and similar test files in the rain.orderbook project, the passthrough vi.mock('rainlanguage/orderbook', async (importOriginal) => { return { ...(await importOriginal()) }; }); block is required for tests to run properly, even when not overriding any exports. This is needed due to the specific Vitest configuration or test environment setup in the project.
Applied to files:
packages/webapp/src/__tests__/Sidebar.test.ts
📚 Learning: 2025-06-30T14:17:16.626Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1926
File: packages/ui-components/src/lib/__mocks__/stores.ts:13-17
Timestamp: 2025-06-30T14:17:16.626Z
Learning: User findolor reports that vi.mock(import('rainlanguage/orderbook'), async (importOriginal) => { ... }) syntax works in their testing environment, despite official Vitest documentation indicating the first argument should be a string. This suggests there may be specific Vitest versions or configurations that support dynamic import() as the first argument to vi.mock().
Applied to files:
packages/webapp/src/__tests__/Sidebar.test.ts
📚 Learning: 2025-06-17T14:55:22.914Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1936
File: packages/ui-components/vite.config.ts:21-23
Timestamp: 2025-06-17T14:55:22.914Z
Learning: In the rain.orderbook project, the Vite configuration uses `'import.meta.vitest': 'undefined'` (as a string) combined with conditional `if (import.meta.vitest)` checks for in-source testing. The mock files are excluded from test execution using `exclude: ['src/lib/__mocks__/**/*.ts']`. This configuration successfully allows dev builds to work without `vi` undefined errors, despite the theoretical expectation that the string "undefined" would be truthy and cause issues.
Applied to files:
packages/webapp/src/__tests__/Sidebar.test.ts
📚 Learning: 2025-04-15T12:35:56.008Z
Learnt from: hardingjam
Repo: rainlanguage/rain.orderbook PR: 1669
File: packages/webapp/src/routes/+layout.ts:82-261
Timestamp: 2025-04-15T12:35:56.008Z
Learning: When testing Svelte applications, focus on application logic rather than testing Svelte's built-in reactive store system. Testing framework functionality (like Svelte's store reactivity) is generally unnecessary in application tests.
Applied to files:
packages/webapp/src/__tests__/Sidebar.test.ts
📚 Learning: 2025-07-09T12:35:45.699Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1974
File: packages/ui-components/src/__tests__/DeploymentSteps.test.ts:123-126
Timestamp: 2025-07-09T12:35:45.699Z
Learning: In packages/ui-components/src/__tests__/DeploymentSteps.test.ts, findolor prefers to keep mock initializations (like setSelectToken) in individual test cases rather than consolidating them into shared beforeEach blocks, even when it results in duplication.
Applied to files:
packages/webapp/src/__tests__/Sidebar.test.ts
📚 Learning: 2025-04-07T08:18:36.473Z
Learnt from: hardingjam
Repo: rainlanguage/rain.orderbook PR: 1565
File: packages/webapp/src/routes/deploy/layout.test.ts:12-29
Timestamp: 2025-04-07T08:18:36.473Z
Learning: In test files for this project, hardingjam prefers to use custom mocks (such as for localStorage) rather than relying on environment-provided implementations, as this allows for spying on individual methods and having precise control over implementation details for more robust testing.
Applied to files:
packages/webapp/src/__tests__/Sidebar.test.ts
📚 Learning: 2025-03-26T15:00:17.997Z
Learnt from: hardingjam
Repo: rainlanguage/rain.orderbook PR: 1516
File: packages/webapp/src/routes/deploy/[strategyName]/layout.test.ts:0-0
Timestamp: 2025-03-26T15:00:17.997Z
Learning: For Rain Orderbook projects, there's a preference not to include tests for SvelteKit methods (like parent function rejections) in test files, as these are considered framework responsibilities rather than application code that needs testing.
Applied to files:
packages/webapp/src/__tests__/Sidebar.test.ts
📚 Learning: 2025-03-24T12:27:07.862Z
Learnt from: hardingjam
Repo: rainlanguage/rain.orderbook PR: 1494
File: packages/ui-components/src/__tests__/WalletProvider.test.ts:18-28
Timestamp: 2025-03-24T12:27:07.862Z
Learning: In the WalletProvider tests, verifying that setAccountContext is called with the correct store is sufficient. Additional testing of Svelte's store implementation (like subscribing to verify the store value) is unnecessary as it would just be testing the framework itself.
Applied to files:
packages/webapp/src/__tests__/Sidebar.test.ts
📚 Learning: 2025-05-14T05:13:59.713Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1744
File: crates/subgraph/src/orderbook_client.rs:44-46
Timestamp: 2025-05-14T05:13:59.713Z
Learning: In the rain.orderbook project, WASM dependencies are intentionally made available in non-WASM targets to facilitate testing of WASM-related functionality, so conditional compilation guards like `#[cfg(target_family = "wasm")]` should not be added to imports or implementations that may be needed for tests.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/leadership.rs
📚 Learning: 2025-07-18T10:31:05.498Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2008
File: crates/common/src/raindex_client/add_orders.rs:85-86
Timestamp: 2025-07-18T10:31:05.498Z
Learning: In the rainlanguage/rain.orderbook codebase, cfg-guarded imports like `#[cfg(not(target_family = "wasm"))] use super::*;` in test modules are sometimes needed to fix compiler warnings, even when similar imports exist in nested sub-modules. These should not be removed as they serve a specific purpose in the compilation process.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/leadership.rscrates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
📚 Learning: 2025-04-30T09:28:36.960Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1715
File: crates/js_api/src/common/mod.rs:111-118
Timestamp: 2025-04-30T09:28:36.960Z
Learning: In the rain.orderbook repository, the WASM tests are already properly configured with conditional compilation using `#[cfg(target_family = "wasm")]` and `#[cfg(not(target_family = "wasm"))]`, and don't require additional `wasm_bindgen_test_configure!(run_in_browser)` directives.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/leadership.rs
📚 Learning: 2025-05-27T06:16:35.738Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1874
File: tauri-app/src-tauri/src/transaction_status.rs:69-127
Timestamp: 2025-05-27T06:16:35.738Z
Learning: In tauri-app/src-tauri/src/transaction_status.rs, directly accessing internal RwLock state in tests using `notice.0.read().unwrap()` is acceptable and does not require encapsulation through public getter methods.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/leadership.rs
📚 Learning: 2025-10-06T11:13:29.956Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2123
File: crates/common/src/raindex_client/local_db/mod.rs:23-29
Timestamp: 2025-10-06T11:13:29.956Z
Learning: In `crates/common/src/raindex_client/local_db/mod.rs`, the `Default` implementation for `LocalDb` that creates an RPC client pointing to `http://localhost:4444` is acceptable because the RPC client must be explicitly configured before actual usage in production scenarios.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/leadership.rscrates/common/src/raindex_client/local_db/pipeline/runner/mod.rscrates/common/src/raindex_client/local_db/mod.rscrates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
📚 Learning: 2025-10-06T14:41:41.909Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2159
File: crates/cli/src/commands/local_db/sync/runner/mod.rs:52-113
Timestamp: 2025-10-06T14:41:41.909Z
Learning: The local DB sync CLI command (crates/cli/src/commands/local_db/sync/) is designed for CI-only usage, and simple println! statements are preferred over structured logging for status messages.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/mod.rscrates/common/src/raindex_client/local_db/mod.rscrates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
📚 Learning: 2025-06-17T16:21:24.384Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1903
File: crates/settings/src/yaml/orderbook.rs:371-377
Timestamp: 2025-06-17T16:21:24.384Z
Learning: In crates/settings/src/yaml/orderbook.rs tests, the user findolor considers RPC ordering in Vec<Url> assertions to be intentional and not a test brittleness issue. The ordering of RPCs in tests should be preserved as specified.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/mod.rs
📚 Learning: 2025-07-21T16:34:04.947Z
Learnt from: 0xgleb
Repo: rainlanguage/rain.orderbook PR: 1911
File: crates/common/src/raindex_client/orders.rs:720-720
Timestamp: 2025-07-21T16:34:04.947Z
Learning: In the rainlanguage/rain.orderbook codebase, user 0xgleb prefers using `.unwrap()` in test code rather than `.expect()` with descriptive messages, considering the direct unwrap approach acceptable for test contexts where failures should be fast and clear.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/mod.rs
📚 Learning: 2025-05-20T10:20:08.206Z
Learnt from: 0xgleb
Repo: rainlanguage/rain.orderbook PR: 1859
File: crates/quote/src/quote_debug.rs:472-492
Timestamp: 2025-05-20T10:20:08.206Z
Learning: In the Rain Orderbook codebase, the `#[tokio::test(flavor = "multi_thread")]` annotation is specifically needed for tests that use `LocalEvm`, not just for consistency across all async tests.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/mod.rscrates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
📚 Learning: 2025-10-06T14:13:18.531Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2155
File: crates/common/src/raindex_client/trades.rs:133-152
Timestamp: 2025-10-06T14:13:18.531Z
Learning: In the rain.orderbook codebase, the `page` parameter in `RaindexOrder::get_trades_list` method (in crates/common/src/raindex_client/trades.rs) is kept for backwards compatibility with subgraph logic, but the LocalDb fast-path intentionally returns all trades without implementing pagination.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
📚 Learning: 2025-07-15T08:01:38.534Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1994
File: crates/common/src/raindex_client/vaults.rs:282-292
Timestamp: 2025-07-15T08:01:38.534Z
Learning: In the rainlanguage/rain.orderbook codebase, findolor prefers to avoid concurrency optimizations like using `futures::future::try_join_all` for parallel processing of balance changes, considering such optimizations "not that critical at the moment" when the performance impact is minimal.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
📚 Learning: 2025-10-06T11:44:07.888Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2145
File: crates/common/src/raindex_client/local_db/query/create_tables/query.sql:71-72
Timestamp: 2025-10-06T11:44:07.888Z
Learning: The local DB feature in the rain.orderbook codebase is not live yet (as of PR #2145), so schema migrations for existing databases are not required when modifying table structures in `crates/common/src/raindex_client/local_db/query/create_tables/query.sql`.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
🧬 Code graph analysis (5)
crates/common/src/raindex_client/local_db/pipeline/runner/config.rs (1)
crates/common/src/local_db/pipeline/runner/utils.rs (2)
build_runner_targets(57-100)parse_runner_settings(30-39)
packages/webapp/src/lib/stores/localDbStatus.ts (1)
crates/common/src/raindex_client/local_db/mod.rs (4)
failure(189-197)failure(222-224)syncing(179-187)syncing(218-220)
packages/webapp/src/__tests__/Sidebar.test.ts (1)
packages/webapp/src/lib/stores/localDbStatus.ts (2)
networkStatuses(4-4)updateNetworkStatus(6-11)
crates/common/src/raindex_client/local_db/pipeline/runner/leadership.rs (1)
crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs (6)
new(326-340)new(568-575)network_key(45-45)network_key(57-59)network_key(381-383)network_key(598-600)
crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs (2)
crates/common/src/raindex_client/local_db/pipeline/runner/mod.rs (11)
network_key(102-104)chain_id(106-108)new(284-287)new(352-354)new(382-386)new(613-618)new(706-711)new(736-738)new(818-824)new(871-876)from_config(81-100)crates/common/src/raindex_client/local_db/pipeline/runner/config.rs (1)
from_global_settings(17-61)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (18)
- GitHub Check: standard-tests (ubuntu-latest, rainix-rs-artifacts, true)
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-legal)
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-static)
- GitHub Check: standard-tests (ubuntu-latest, rainix-wasm-artifacts)
- GitHub Check: standard-tests (ubuntu-latest, ob-rs-test, true)
- GitHub Check: standard-tests (ubuntu-latest, rainix-rs-static)
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-artifacts)
- GitHub Check: standard-tests (ubuntu-latest, rainix-wasm-browser-test)
- GitHub Check: standard-tests (ubuntu-latest, test-js-bindings)
- GitHub Check: standard-tests (ubuntu-latest, rainix-wasm-test)
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-test)
- GitHub Check: test
- GitHub Check: git-clean
- GitHub Check: test
- GitHub Check: test
- GitHub Check: Deploy-Docs-Preview
- GitHub Check: build-tauri (ubuntu-22.04, true)
- GitHub Check: Deploy-Preview-Push
🔇 Additional comments (23)
packages/webapp/src/lib/stores/localDbStatus.ts (4)
1-2: LGTM: Imports are correct.The imports properly bring in the necessary types from the orderbook package and Svelte store utilities.
4-4: LGTM: Store initialization is correct.The
networkStatusesstore is properly initialized as an empty Map with correct typing.
6-11: LGTM: Correct Map update pattern for Svelte reactivity.The function properly creates a new Map instance after updating, which is essential for triggering Svelte's reactivity system. This is the correct pattern for mutable data structures in Svelte stores.
33-33: LGTM: Export alias maintains backward compatibility.Exporting
localDbStatusas an alias foraggregateStatusallows existing code to continue using the familiar name while the internal implementation has changed to support per-network tracking.packages/webapp/src/__tests__/Sidebar.test.ts (3)
5-5: LGTM: Import updated correctly.The test now imports the new
networkStatusesandupdateNetworkStatusexports, aligning with the refactored store API.
58-58: LGTM: Test cleanup updated correctly.The cleanup now properly resets
networkStatusesto an empty Map, ensuring test isolation with the new store structure.
142-148: LGTM: Test updated to use new API correctly.The test properly uses
updateNetworkStatuswith a completeNetworkSyncStatuspayload including all required fields (networkKey, chainId, status, schedulerState, error).packages/webapp/src/routes/+layout.svelte (3)
22-22: LGTM: Import updated correctly.The import change from
localDbStatustoupdateNetworkStatusaligns with the new callback-based pattern where the Rust scheduler invokes the callback with per-network status updates.
42-42: LGTM: Callback pattern implemented correctly.Passing
updateNetworkStatustostartLocalDbSchedulerenables the Rust scheduler to emit per-network status updates back to the webapp, as specified in the PR objectives.
45-61: LGTM: Error handling updated correctly.The error handling properly uses
updateNetworkStatuswith appropriate field values. Using'unknown'for networkKey and0for chainId as sentinel values is safe—these values are stored internally in thelocalDbStatusstore but never exposed to UI components. TheaggregateStatusderived store only processes thestatusfield, andLocalDbStatusCardconsumes only thestatusanderrorfields. These sentinel values remain isolated from components that might reference networkKey or chainId.crates/common/src/local_db/pipeline/runner/mod.rs (1)
39-44: LGTM! Clean addition of RunOutcome enum.The
RunOutcomeenum elegantly extends the runner's return type to distinguish between actual run results and leadership acquisition failures. This design cleanly supports the per-network independent sync cycles objective without breaking the existingRunReportstructure.crates/common/src/raindex_client/local_db/pipeline/runner/config.rs (1)
68-185: Solid test coverage for NetworkRunnerConfig.The tests thoroughly cover the filtering logic, error handling for unknown networks, and target construction. The test fixture
sample_settings_yaml()provides realistic configuration for validation.crates/common/src/raindex_client/local_db/pipeline/runner/leadership.rs (2)
56-79: Well-designed per-network leadership with clear lock naming.The extension to support per-network Web Locks is clean:
network_keyfield enables per-network lock isolationlock_name()generates deterministic, collision-free lock names- The
cfg_attr(not(any(target_family = "wasm", test)), allow(dead_code))annotation correctly handles the field's conditional usageThis directly addresses the PR objective of ensuring each network runs independently.
258-290: Comprehensive tests for per-network leadership.The new tests thoroughly cover the network key handling and lock name generation, including the important case that different networks produce different lock names to ensure isolation.
crates/common/src/raindex_client/local_db/pipeline/runner/mod.rs (3)
81-100: Clean from_config constructor for per-network runners.The
from_configconstructor properly initializes network-specific fields (network_key,chain_id) fromNetworkRunnerConfig, enabling per-network runners to be created with their scoped settings and targets.
110-169: Correct RunOutcome integration in run() method.The
run()method properly:
- Returns
RunOutcome::NotLeaderwhen leadership acquisition fails (line 117)- Wraps manifest failures and execution results in
RunOutcome::Report- Uses
has_provisioned_dumpsto avoid redundant downloads on subsequent runsThe control flow ensures leadership is always checked first before any work is performed.
1148-1153: Useful unwrap_report helper for tests.The
unwrap_reporthelper cleanly extractsRunReportfromRunOutcome::Reportand panics onNotLeader, making test assertions more readable.crates/common/src/raindex_client/local_db/mod.rs (2)
132-198: Well-designed per-network status types.The new types effectively model per-network sync status:
SchedulerStatecleanly distinguishes Leader vs NotLeaderNetworkSyncStatusaggregates all relevant per-network info- Constructor helpers (
active,syncing,failure) provide convenient creation patternsThe assumption that
syncing()andfailure()always haveSchedulerState::Leaderis correct—you can only be syncing or failing if you're the leader.
267-280: Simplified synchronous stop.Changing
stop_local_db_schedulerfrom async to sync simplifies the API and aligns with the fire-and-forget stop pattern via the stop flag.crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs (4)
82-180: Solid multi-network orchestration in start().The refactored
start()function correctly implements the per-network independent sync cycles:
- Deterministic ordering: Network keys are collected and sorted (lines 89-96)
- One-time schema init: Bootstrap runs once before spawning loops (lines 118-119)
- Graceful degradation: Per-network setup failures emit status and continue to other networks (lines 135-163)
- Independent loops: Each network gets its own
spawn_network_loopcallThis directly addresses the PR objective that "a slow/failing network does not block healthy networks."
196-279: Correct per-network loop implementation with leadership tracking.The
run_network_loopproperly implements the per-network scheduling:
- Syncing emission timing: Only emits "syncing" status after confirming leadership in a previous cycle (lines 214-219), preventing spurious syncing states
- RunOutcome handling: Correctly distinguishes
Report(was leader) fromNotLeader(wasn't leader)- Error handling: On error (lines 260-269),
was_leader_last_cycle = trueis correct becauseClientRunner::run()only errors after leadership is acquiredThis fulfills the requirement that "status callbacks emit per-network statuses including scheduler/leadership state."
607-646: Excellent integration test for independent network loops.The
slow_network_does_not_block_fast_networkstest is a key acceptance criterion verification. It confirms that:
- Fast networks complete multiple cycles while slow networks are still processing
- Networks truly run independently via separate spawned loops
This directly validates the PR's core objective.
66-80: SchedulerHandle correctly exposes network keys.The
network_keysfield and accessor enable callers to know which networks are being managed by the scheduler, supporting UI components that need to display per-network status.
| let chain_id = filtered_orderbooks | ||
| .values() | ||
| .next() | ||
| .map(|ob| ob.network.chain_id) | ||
| .ok_or_else(|| { | ||
| LocalDbError::CustomError(format!( | ||
| "could not determine chain_id for network: {}", | ||
| network_key | ||
| )) | ||
| })?; |
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.
🧹 Nitpick | 🔵 Trivial
Unreachable error branch in chain_id extraction.
The ok_or_else closure on lines 39-44 is unreachable because filtered_orderbooks is guaranteed non-empty after the check at lines 28-33. While this doesn't cause bugs, it's dead code.
🔎 Proposed simplification
- let chain_id = filtered_orderbooks
- .values()
- .next()
- .map(|ob| ob.network.chain_id)
- .ok_or_else(|| {
- LocalDbError::CustomError(format!(
- "could not determine chain_id for network: {}",
- network_key
- ))
- })?;
+ // Safe unwrap: filtered_orderbooks is guaranteed non-empty after the check above
+ let chain_id = filtered_orderbooks
+ .values()
+ .next()
+ .map(|ob| ob.network.chain_id)
+ .expect("filtered_orderbooks is non-empty");📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| let chain_id = filtered_orderbooks | |
| .values() | |
| .next() | |
| .map(|ob| ob.network.chain_id) | |
| .ok_or_else(|| { | |
| LocalDbError::CustomError(format!( | |
| "could not determine chain_id for network: {}", | |
| network_key | |
| )) | |
| })?; | |
| // Safe unwrap: filtered_orderbooks is guaranteed non-empty after the check above | |
| let chain_id = filtered_orderbooks | |
| .values() | |
| .next() | |
| .map(|ob| ob.network.chain_id) | |
| .expect("filtered_orderbooks is non-empty"); |
🤖 Prompt for AI Agents
In crates/common/src/raindex_client/local_db/pipeline/runner/config.rs around
lines 35 to 44, the ok_or_else closure used to produce a LocalDbError is
unreachable because filtered_orderbooks was already checked to be non-empty
earlier; remove the dead ok_or_else and directly extract the chain_id from the
first value (e.g. .values().next().map(|ob| ob.network.chain_id).unwrap() or
.values().next().expect("...").network.chain_id) or otherwise use expect with a
clear message referencing network_key to preserve intent.
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.
we can keep for now. we have another PR that improves more stuff
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.
@findolor, sounds good! I'll leave this as-is for now. Looking forward to the improvements in the upcoming PR. 👍
🧠 Learnings used
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2344
File: crates/common/src/local_db/pipeline/runner/mod.rs:18-31
Timestamp: 2025-12-03T10:40:25.429Z
Learning: In `crates/common/src/local_db/pipeline/runner/mod.rs`, the `TargetSuccess` struct does not need separate `ob_id` or `orderbook_key` fields because the contained `SyncOutcome` already includes orderbook identification information such as chain_id and orderbook_address. This avoids redundant data duplication.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2202
File: crates/common/src/raindex_client/local_db/sync.rs:33-34
Timestamp: 2025-10-14T07:51:55.148Z
Learning: In `crates/common/src/raindex_client/local_db/sync.rs`, the hard-coded `DEFAULT_SYNC_CHAIN_ID` constant (set to `SUPPORTED_LOCAL_DB_CHAINS[0]`) will be replaced with proper chain ID handling in downstream PRs as part of the multi-network/orderbook implementation.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2237
File: crates/common/src/raindex_client/local_db/sync.rs:79-89
Timestamp: 2025-10-18T10:38:41.273Z
Learning: In `crates/common/src/raindex_client/local_db/sync.rs`, the sync_database method currently only supports indexing a single orderbook per chain ID, which is why `.first()` is used to select the orderbook configuration. Multi-orderbook support per chain ID is planned for future PRs.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1477
File: crates/settings/src/remote_networks.rs:40-75
Timestamp: 2025-04-03T09:45:04.200Z
Learning: The RemoteNetworksCfg implementation in crates/settings/src/remote_networks.rs intentionally fetches remote networks sequentially rather than in parallel.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1938
File: crates/settings/src/yaml/orderbook.rs:185-199
Timestamp: 2025-06-18T19:24:40.518Z
Learning: In crates/settings/src/yaml/orderbook.rs, the user prefers not to refactor get_orderbook_by_network_key to handle multiple orderbooks per network key since their current architecture maintains a one-to-one mapping between orderbooks and networks. They would consider the refactoring if the system evolves to support multiple orderbooks per network in the future.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1956
File: crates/common/src/raindex_client/mod.rs:116-135
Timestamp: 2025-07-04T10:26:24.289Z
Learning: In crates/common/src/raindex_client/mod.rs, the get_multi_subgraph_args method intentionally treats Some(empty vector) the same as None for chain_ids parameter. Both cases should return all networks to support UI behavior where no selection or empty selection means "show all networks". Only when specific chain IDs are provided should the results be filtered.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1994
File: crates/common/src/raindex_client/vaults.rs:282-292
Timestamp: 2025-07-15T08:01:38.534Z
Learning: In the rainlanguage/rain.orderbook codebase, findolor prefers to avoid concurrency optimizations like using `futures::future::try_join_all` for parallel processing of balance changes, considering such optimizations "not that critical at the moment" when the performance impact is minimal.
Learnt from: 0xgleb
Repo: rainlanguage/rain.orderbook PR: 1911
File: crates/common/src/raindex_client/orders.rs:720-720
Timestamp: 2025-07-21T16:34:04.947Z
Learning: In the rainlanguage/rain.orderbook codebase, user 0xgleb prefers using `.unwrap()` in test code rather than `.expect()` with descriptive messages, considering the direct unwrap approach acceptable for test contexts where failures should be fast and clear.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1956
File: crates/common/src/raindex_client/add_orders.rs:132-132
Timestamp: 2025-07-04T10:24:29.750Z
Learning: In the rain.orderbook codebase, findolor prefers to use `unwrap_or("")` for optional frontmatter in dotrain parsing, allowing empty strings to be handled by downstream validation in `NewConfig::try_from_yaml()` rather than adding explicit early validation checks at the extraction point.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1941
File: crates/settings/src/yaml/orderbook.rs:112-123
Timestamp: 2025-06-20T07:26:50.488Z
Learning: In crates/settings/src/yaml/orderbook.rs, the user prefers to keep the get_network_by_chain_id implementation simple with O(n) lookup rather than adding caching complexity for performance optimization, even if the method might be called frequently.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1938
File: crates/settings/src/yaml/orderbook.rs:180-199
Timestamp: 2025-06-18T18:24:32.049Z
Learning: In crates/settings/src/yaml/orderbook.rs, the user prefers to avoid refactoring duplicate search logic between get_orderbook_by_address and get_orderbook_by_network_key when there are only 2 functions, indicating they would consider it if more similar functions are added in the future.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1903
File: crates/cli/src/commands/order/calldata.rs:47-57
Timestamp: 2025-06-17T16:46:19.035Z
Learning: In the CLI command `crates/cli/src/commands/order/calldata.rs`, the user prefers to let lower-level errors from `try_into_call()` bubble up when the RPCs list is empty, rather than adding early validation checks with custom error messages.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1975
File: crates/js_api/src/config.rs:44-45
Timestamp: 2025-07-09T07:42:48.458Z
Learning: User findolor prefers to defer code improvements and refactoring suggestions to future PRs when they are not directly related to the current PR's scope, even when the suggestions are valid improvements.
| export const aggregateStatus = derived(networkStatuses, ($map) => { | ||
| if ($map.size === 0) { | ||
| return { status: 'active' as LocalDbStatus, error: undefined }; | ||
| } | ||
|
|
||
| const statuses = Array.from($map.values()); | ||
|
|
||
| const failure = statuses.find((s) => s.status === 'failure'); | ||
| if (failure) { | ||
| return { status: 'failure' as LocalDbStatus, error: failure.error }; | ||
| } | ||
|
|
||
| const syncing = statuses.find((s) => s.status === 'syncing'); | ||
| if (syncing) { | ||
| return { status: 'syncing' as LocalDbStatus, error: undefined }; | ||
| } | ||
|
|
||
| return { status: 'active' as LocalDbStatus, error: undefined }; | ||
| }); |
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.
🧹 Nitpick | 🔵 Trivial
LGTM: Aggregation logic is correct.
The derived store correctly implements the failure > syncing > active priority order as specified in the PR objectives. The logic properly handles the empty map case and finds the first matching status.
Optional: Consider removing explicit type assertions if LocalDbStatus is a union type
If LocalDbStatus is defined as a union type like 'active' | 'syncing' | 'failure', the type assertions may be unnecessary:
export const aggregateStatus = derived(networkStatuses, ($map) => {
if ($map.size === 0) {
- return { status: 'active' as LocalDbStatus, error: undefined };
+ return { status: 'active', error: undefined };
}
const statuses = Array.from($map.values());
const failure = statuses.find((s) => s.status === 'failure');
if (failure) {
- return { status: 'failure' as LocalDbStatus, error: failure.error };
+ return { status: 'failure', error: failure.error };
}
const syncing = statuses.find((s) => s.status === 'syncing');
if (syncing) {
- return { status: 'syncing' as LocalDbStatus, error: undefined };
+ return { status: 'syncing', error: undefined };
}
- return { status: 'active' as LocalDbStatus, error: undefined };
+ return { status: 'active', error: undefined };
});This only applies if TypeScript can infer the type correctly without the assertions.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export const aggregateStatus = derived(networkStatuses, ($map) => { | |
| if ($map.size === 0) { | |
| return { status: 'active' as LocalDbStatus, error: undefined }; | |
| } | |
| const statuses = Array.from($map.values()); | |
| const failure = statuses.find((s) => s.status === 'failure'); | |
| if (failure) { | |
| return { status: 'failure' as LocalDbStatus, error: failure.error }; | |
| } | |
| const syncing = statuses.find((s) => s.status === 'syncing'); | |
| if (syncing) { | |
| return { status: 'syncing' as LocalDbStatus, error: undefined }; | |
| } | |
| return { status: 'active' as LocalDbStatus, error: undefined }; | |
| }); | |
| export const aggregateStatus = derived(networkStatuses, ($map) => { | |
| if ($map.size === 0) { | |
| return { status: 'active', error: undefined }; | |
| } | |
| const statuses = Array.from($map.values()); | |
| const failure = statuses.find((s) => s.status === 'failure'); | |
| if (failure) { | |
| return { status: 'failure', error: failure.error }; | |
| } | |
| const syncing = statuses.find((s) => s.status === 'syncing'); | |
| if (syncing) { | |
| return { status: 'syncing', error: undefined }; | |
| } | |
| return { status: 'active', error: undefined }; | |
| }); |
🤖 Prompt for AI Agents
In packages/webapp/src/lib/stores/localDbStatus.ts around lines 13 to 31, remove
the unnecessary explicit "as LocalDbStatus" type assertions on returned status
values (e.g., 'active' as LocalDbStatus, 'failure' as LocalDbStatus, 'syncing'
as LocalDbStatus) so TypeScript can infer the union type directly; update the
return expressions to return plain string literals and ensure the LocalDbStatus
union is imported/visible in this file so no type errors appear.
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.
it's fine we can keep this as it is
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.
@findolor, sounds good! The explicit type assertions provide clarity and are perfectly valid. 👍
🧠 Learnings used
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1917
File: tauri-app/src/lib/stores/order.ts:10-15
Timestamp: 2025-06-11T11:27:14.391Z
Learning: In this codebase, Svelte writable/derived stores (e.g., `subgraph` in `tauri-app/src/lib/stores/settings.ts`) expose a custom asynchronous `.load()` helper that retrieves the current value, so calls like `await subgraph.load()` are valid.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2278
File: packages/webapp/src/lib/services/startLocalDbSync.ts:23-29
Timestamp: 2025-10-29T13:29:29.578Z
Learning: In packages/webapp/src/lib/services/startLocalDbSync.ts, the hard-coded default orderbook address '0x2f209e5b67A33B8fE96E28f24628dF6Da301c8eB' is a temporary placeholder that will be removed when new sync logic is introduced in the Raindex client, as documented in the NOTE comment.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2202
File: crates/common/src/raindex_client/local_db/sync.rs:33-34
Timestamp: 2025-10-14T07:51:55.148Z
Learning: In `crates/common/src/raindex_client/local_db/sync.rs`, the hard-coded `DEFAULT_SYNC_CHAIN_ID` constant (set to `SUPPORTED_LOCAL_DB_CHAINS[0]`) will be replaced with proper chain ID handling in downstream PRs as part of the multi-network/orderbook implementation.
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.
Actionable comments posted: 1
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
🧰 Additional context used
📓 Path-based instructions (3)
crates/**/*.rs
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
crates/**/*.rs: For Rust crates incrates/*, run lints usingnix develop -c cargo clippy --workspace --all-targets --all-features -D warnings
For Rust crates incrates/*, run tests usingnix develop -c cargo test --workspaceor--package <crate>
Files:
crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
**/crates/**
📄 CodeRabbit inference engine (AGENTS.md)
Rust workspace organized as
crates/*with subdirectories: cli, common, bindings, js_api, quote, subgraph, settings, math, integration_tests
Files:
crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
**/*.rs
📄 CodeRabbit inference engine (AGENTS.md)
**/*.rs: Rust: format code withnix develop -c cargo fmt --all
Rust: lint withnix develop -c rainix-rs-static(preconfigured flags included)
Rust: crates and modules usesnake_case; types usePascalCase
Files:
crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
🧠 Learnings (6)
📓 Common learnings
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2202
File: crates/common/src/raindex_client/local_db/sync.rs:33-34
Timestamp: 2025-10-14T07:51:55.148Z
Learning: In `crates/common/src/raindex_client/local_db/sync.rs`, the hard-coded `DEFAULT_SYNC_CHAIN_ID` constant (set to `SUPPORTED_LOCAL_DB_CHAINS[0]`) will be replaced with proper chain ID handling in downstream PRs as part of the multi-network/orderbook implementation.
📚 Learning: 2025-12-03T10:40:25.429Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2344
File: crates/common/src/local_db/pipeline/runner/mod.rs:18-31
Timestamp: 2025-12-03T10:40:25.429Z
Learning: In `crates/common/src/local_db/pipeline/runner/mod.rs`, the `TargetSuccess` struct does not need separate `ob_id` or `orderbook_key` fields because the contained `SyncOutcome` already includes orderbook identification information such as chain_id and orderbook_address. This avoids redundant data duplication.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
📚 Learning: 2025-10-14T07:51:55.148Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2202
File: crates/common/src/raindex_client/local_db/sync.rs:33-34
Timestamp: 2025-10-14T07:51:55.148Z
Learning: In `crates/common/src/raindex_client/local_db/sync.rs`, the hard-coded `DEFAULT_SYNC_CHAIN_ID` constant (set to `SUPPORTED_LOCAL_DB_CHAINS[0]`) will be replaced with proper chain ID handling in downstream PRs as part of the multi-network/orderbook implementation.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
📚 Learning: 2025-10-06T11:13:29.956Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2123
File: crates/common/src/raindex_client/local_db/mod.rs:23-29
Timestamp: 2025-10-06T11:13:29.956Z
Learning: In `crates/common/src/raindex_client/local_db/mod.rs`, the `Default` implementation for `LocalDb` that creates an RPC client pointing to `http://localhost:4444` is acceptable because the RPC client must be explicitly configured before actual usage in production scenarios.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
📚 Learning: 2025-10-18T10:38:41.273Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2237
File: crates/common/src/raindex_client/local_db/sync.rs:79-89
Timestamp: 2025-10-18T10:38:41.273Z
Learning: In `crates/common/src/raindex_client/local_db/sync.rs`, the sync_database method currently only supports indexing a single orderbook per chain ID, which is why `.first()` is used to select the orderbook configuration. Multi-orderbook support per chain ID is planned for future PRs.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
📚 Learning: 2025-04-03T09:45:04.200Z
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1477
File: crates/settings/src/remote_networks.rs:40-75
Timestamp: 2025-04-03T09:45:04.200Z
Learning: The RemoteNetworksCfg implementation in crates/settings/src/remote_networks.rs intentionally fetches remote networks sequentially rather than in parallel.
Applied to files:
crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (16)
- GitHub Check: build-tauri (ubuntu-22.04, true)
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-legal)
- GitHub Check: standard-tests (ubuntu-latest, rainix-wasm-test)
- GitHub Check: standard-tests (ubuntu-latest, ob-rs-test, true)
- GitHub Check: standard-tests (ubuntu-latest, rainix-wasm-artifacts)
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-static)
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-artifacts)
- GitHub Check: standard-tests (ubuntu-latest, rainix-rs-artifacts, true)
- GitHub Check: standard-tests (ubuntu-latest, rainix-rs-static)
- GitHub Check: standard-tests (ubuntu-latest, rainix-sol-test)
- GitHub Check: git-clean
- GitHub Check: test
- GitHub Check: test
- GitHub Check: test
- GitHub Check: Deploy-Preview-Push
- GitHub Check: Deploy-Docs-Preview
🔇 Additional comments (8)
crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs (8)
1-37: LGTM!Imports and type definitions are well-organized. The use of
Rc<Cell<bool>>for the stop flag is appropriate for the single-threaded WASM context.
66-80: LGTM!The
SchedulerHandledesign is clean. The synchronousstop()method appropriately sets a flag that running loops check, and exposingnetwork_keysprovides useful visibility into the tracked networks.
82-130: Well-structured multi-network orchestration.The start function correctly:
- Extracts unique network keys and sorts them for deterministic ordering
- Performs one-time schema bootstrap before spawning per-network loops
- Shares a single
stop_flagacross all network loops for unified controlOne minor observation: when bootstrap fails (line 125),
chain_id: 0is used as a placeholder since the failure is global and no network-specific chain ID is available yet. This is acceptable but consider if a sentinel value likeu32::MAXor makingchain_idoptional in error states would be clearer.
131-174: LGTM!The per-network setup correctly:
- Creates network-specific leadership locks via
with_network_key- Continues to the next network on configuration or runner creation failures, ensuring healthy networks proceed independently
- Uses the appropriate
chain_id(0 for config errors, actual value for runner errors)This aligns well with the PR objective that "slow/failing networks no longer block others."
281-287: LGTM!The
emit_network_statushelper is straightforward. Silently ignoring serialization and callback errors is acceptable for status emissions since these are informational and shouldn't interrupt the sync loop.
318-389: LGTM!The
RecordingRunnerwith its outcome queue pattern andDelayedRunnerwith configurable delays provide excellent test infrastructure for verifying the per-network scheduling behavior. The flexible outcome encoding (Some(true)= failure,Some(false)= success,None= NotLeader) enables precise control over test scenarios.
608-648: Excellent test coverage for the core PR objective.The
slow_network_does_not_block_fast_networkstest directly validates the main motivation of this PR - that a slow/failing network doesn't block healthy networks. The test:
- Uses
DelayedRunnerto simulate a slow network (100ms delay)- Verifies fast network completes more cycles than slow network midway through
- Confirms both networks eventually complete cycles
This provides strong confidence that the per-network independent sync cycles work as intended.
57-63: No issues identified. Thenetwork_key()andchain_id()trait method implementations correctly delegate to the inherent methods defined onClientRunnerinrunner/mod.rs(lines 102-107). Due to Rust's method resolution order,self.network_key()andself.chain_id()resolve to the inherent methods, not the trait methods, avoiding any recursion. The inherent methods access the struct fields directly (self.network_key.as_deref()andself.chain_id).
| async fn run_network_loop<R>( | ||
| mut runner: R, | ||
| db: LocalDb, | ||
| callback: Option<Rc<Function>>, | ||
| stop_flag: Rc<Cell<bool>>, | ||
| interval_ms: u32, | ||
| ) where | ||
| R: SchedulerRunner + 'static, | ||
| { | ||
| let network_key = runner.network_key().unwrap_or("unknown").to_string(); | ||
| let chain_id = runner.chain_id().unwrap_or(0); | ||
| let mut was_leader_last_cycle = false; | ||
|
|
||
| spawn_local(async move { | ||
| let mut runner = runner; | ||
| emit_status(status_callback.as_deref(), LocalDbStatusSnapshot::active()); | ||
| loop { | ||
| if stop_flag_task.get() { | ||
| break; | ||
| } | ||
| loop { | ||
| if stop_flag.get() { | ||
| break; | ||
| } | ||
|
|
||
| if was_leader_last_cycle { | ||
| emit_network_status( | ||
| callback.as_deref(), | ||
| NetworkSyncStatus::syncing(network_key.clone(), chain_id), | ||
| ); | ||
| } | ||
|
|
||
| emit_status(status_callback.as_deref(), LocalDbStatusSnapshot::syncing()); | ||
| match runner.run_once(&db).await { | ||
| Ok(report) => { | ||
| match runner.run_once(&db).await { | ||
| Ok(outcome) => match outcome { | ||
| RunOutcome::Report(report) => { | ||
| was_leader_last_cycle = true; | ||
| if report.failures.is_empty() { | ||
| emit_status(status_callback.as_deref(), LocalDbStatusSnapshot::active()); | ||
| emit_network_status( | ||
| callback.as_deref(), | ||
| NetworkSyncStatus::active( | ||
| network_key.clone(), | ||
| chain_id, | ||
| SchedulerState::Leader, | ||
| ), | ||
| ); | ||
| } else { | ||
| let first = &report.failures[0]; | ||
| let msg = format!( | ||
| "ob {:#x} ({}) failed at {:?}: {}", | ||
| "ob {:#x} failed at {:?}: {}", | ||
| first.ob_id.orderbook_address, | ||
| first.ob_id.chain_id, | ||
| first.stage, | ||
| first.error.to_readable_msg() | ||
| ); | ||
| emit_status( | ||
| status_callback.as_deref(), | ||
| LocalDbStatusSnapshot::failure(msg), | ||
| emit_network_status( | ||
| callback.as_deref(), | ||
| NetworkSyncStatus::failure(network_key.clone(), chain_id, msg), | ||
| ); | ||
| } | ||
| } | ||
| Err(err) => emit_status( | ||
| status_callback.as_deref(), | ||
| LocalDbStatusSnapshot::failure(err.to_readable_msg()), | ||
| ), | ||
| } | ||
|
|
||
| if stop_flag_task.get() { | ||
| break; | ||
| RunOutcome::NotLeader => { | ||
| was_leader_last_cycle = false; | ||
| emit_network_status( | ||
| callback.as_deref(), | ||
| NetworkSyncStatus::active( | ||
| network_key.clone(), | ||
| chain_id, | ||
| SchedulerState::NotLeader, | ||
| ), | ||
| ); | ||
| } | ||
| }, | ||
| Err(err) => { | ||
| was_leader_last_cycle = true; | ||
| emit_network_status( | ||
| callback.as_deref(), | ||
| NetworkSyncStatus::failure( | ||
| network_key.clone(), | ||
| chain_id, | ||
| err.to_readable_msg(), | ||
| ), | ||
| ); | ||
| } | ||
|
|
||
| TimeoutFuture::new(interval_ms).await; | ||
| } | ||
|
|
||
| let _ = done_tx.send(()); | ||
| }); | ||
| if stop_flag.get() { | ||
| break; | ||
| } | ||
|
|
||
| SchedulerHandle { | ||
| stop_flag, | ||
| done: Some(done_rx), | ||
| TimeoutFuture::new(interval_ms).await; | ||
| } | ||
| } |
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.
🧹 Nitpick | 🔵 Trivial
Solid per-network loop implementation with one observation.
The loop correctly handles:
- Stop flag checks at two points for prompt termination
- RunOutcome variants (Report with/without failures, NotLeader)
- Error handling that continues the loop
- Leadership state tracking via
was_leader_last_cycle
Note: On the first iteration, no "syncing" status is emitted before run_once (lines 214-219 only emit if was_leader_last_cycle is true). This means the UI won't show a "syncing" indicator until after the first successful cycle completes. Consider if emitting an initial "syncing" status is desirable for immediate UI feedback.
🔎 Optional: Emit initial syncing status
let network_key = runner.network_key().unwrap_or("unknown").to_string();
let chain_id = runner.chain_id().unwrap_or(0);
let mut was_leader_last_cycle = false;
+
+ // Emit initial syncing status for immediate UI feedback
+ emit_network_status(
+ callback.as_deref(),
+ NetworkSyncStatus::syncing(network_key.clone(), chain_id),
+ );
loop {
if stop_flag.get() {
break;
}
- if was_leader_last_cycle {
- emit_network_status(
- callback.as_deref(),
- NetworkSyncStatus::syncing(network_key.clone(), chain_id),
- );
- }
+ if was_leader_last_cycle {
+ emit_network_status(
+ callback.as_deref(),
+ NetworkSyncStatus::syncing(network_key.clone(), chain_id),
+ );
+ }🤖 Prompt for AI Agents
In crates/common/src/raindex_client/local_db/pipeline/runner/scheduler.rs around
lines 196-279, the loop only emits a "syncing" status when was_leader_last_cycle
is true, so nothing is emitted on the very first iteration; to fix, emit an
initial NetworkSyncStatus::syncing before the first run or initialize
was_leader_last_cycle to true so the existing conditional triggers on the first
loop iteration, ensuring immediate UI feedback—either add a one-time
emit_network_status(callback.as_deref(),
NetworkSyncStatus::syncing(network_key.clone(), chain_id)) right before the loop
starts, or set let mut was_leader_last_cycle = true and keep the rest of the
loop unchanged.
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.
this is further enhanced in #2381
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
🏁 Script executed:
#!/bin/bash
# Fetch details about PR #2381 to understand the enhancements
gh pr view 2381 --repo rainlanguage/rain.orderbook --json title,body,state,url
Length of output: 4068
@findolor, thanks for the heads-up! I can see that PR #2381 provides a much more comprehensive solution with granular per-network/per-orderbook sync status, typed SyncPhase enum (FetchingLogs, Decoding, Persisting, etc.), and a fully implemented ClientStatusBus for structured status updates. That definitely addresses the initial status visibility concern and goes well beyond it with detailed phase tracking and error reporting. 👍
The enhanced UI with the expandable status cards and modal looks great for troubleshooting!
🧬 Code Graph Analysis Results
[crates/common/src/raindex_client/local_db/pipeline/runner/mod.rs:81-100]
pub fn from_config(
config: NetworkRunnerConfig,
environment: RunnerEnvironment<B, W, E, T, A, S>,
leadership: L,
) -> Result<Self, LocalDbError> {
let base_targets = config.build_targets()?;
Ok(Self {
network_key: Some(config.network_key),
chain_id: Some(config.chain_id),
settings: config.settings,
base_targets,
manifest_map: ManifestMap::new(),
manifests_loaded: false,
has_provisioned_dumps: false,
environment,
leadership,
leadership_guard: None,
})
}[crates/common/src/raindex_client/local_db/pipeline/runner/config.rs:17-61]
pub fn from_global_settings(
global: &ParsedRunnerSettings,
network_key: &str,
) -> Result<Self, LocalDbError> {
let filtered_orderbooks: HashMap<String, OrderbookCfg> = global
.orderbooks
.iter()
.filter(|(_, ob)| ob.network.key == network_key)
.map(|(k, v)| (k.clone(), v.clone()))
.collect();
if filtered_orderbooks.is_empty() {
return Err(LocalDbError::CustomError(format!(
"no orderbooks found for network: {}",
network_key
)));
}
let chain_id = filtered_orderbooks
.values()
.next()
.map(|ob| ob.network.chain_id)
.ok_or_else(|| {
LocalDbError::CustomError(format!(
"could not determine chain_id for network: {}",
network_key
))
})?;
let filtered_syncs: HashMap<String, LocalDbSyncCfg> = global
.syncs
.iter()
.filter(|(k, _)| *k == network_key)
.map(|(k, v)| (k.clone(), v.clone()))
.collect();
Ok(Self {
network_key: network_key.to_string(),
chain_id,
settings: ParsedRunnerSettings {
orderbooks: filtered_orderbooks,
syncs: filtered_syncs,
},
})
}[crates/common/src/raindex_client/local_db/pipeline/runner/environment.rs:13-39]
pub fn default_environment() -> RunnerEnvironment<
ClientBootstrapAdapter,
DefaultWindowPipeline,
DefaultEventsPipeline,
DefaultTokensPipeline,
DefaultApplyPipeline,
ClientStatusBus,
> {
RunnerEnvironment::new(
default_manifest_fetcher(),
default_dump_downloader(),
Arc::new(|target: &RunnerTarget| {
let events =
DefaultEventsPipeline::with_regular_rpcs(target.inputs.metadata_rpcs.clone())?;
let tokens = DefaultTokensPipeline::new(target.inputs.metadata_rpcs.clone())?;
Ok(EnginePipelines::new(
ClientBootstrapAdapter::new(),
DefaultWindowPipeline::new(),
events,
tokens,
DefaultApplyPipeline::new(),
ClientStatusBus::new(),
))
}),
)
}[crates/common/src/raindex_client/local_db/pipeline/runner/utils.rs:30-39]
pub fn parse_runner_settings(settings_yaml: &str) -> Result<ParsedRunnerSettings, LocalDbError> {
let orderbook_yaml = OrderbookYaml::new(
vec![settings_yaml.to_owned()],
OrderbookYamlValidation::default(),
)?;
let orderbooks = orderbook_yaml.get_orderbooks()?;
let syncs = orderbook_yaml.get_local_db_syncs()?;
Ok(ParsedRunnerSettings { orderbooks, syncs })
}[crates/common/src/raindex_client/local_db/pipeline/runner/mod.rs:102-104]
pub fn network_key(&self) -> Option<&str> {
self.network_key.as_deref()
}[crates/common/src/raindex_client/local_db/pipeline/runner/mod.rs:106-108]
pub fn chain_id(&self) -> Option<u32> {
self.chain_id
}🧠 Learnings used
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2202
File: crates/common/src/raindex_client/local_db/sync.rs:33-34
Timestamp: 2025-10-14T07:51:55.148Z
Learning: In `crates/common/src/raindex_client/local_db/sync.rs`, the hard-coded `DEFAULT_SYNC_CHAIN_ID` constant (set to `SUPPORTED_LOCAL_DB_CHAINS[0]`) will be replaced with proper chain ID handling in downstream PRs as part of the multi-network/orderbook implementation.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2237
File: crates/common/src/raindex_client/local_db/sync.rs:79-89
Timestamp: 2025-10-18T10:38:41.273Z
Learning: In `crates/common/src/raindex_client/local_db/sync.rs`, the sync_database method currently only supports indexing a single orderbook per chain ID, which is why `.first()` is used to select the orderbook configuration. Multi-orderbook support per chain ID is planned for future PRs.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1994
File: crates/common/src/raindex_client/vaults.rs:282-292
Timestamp: 2025-07-15T08:01:38.534Z
Learning: In the rainlanguage/rain.orderbook codebase, findolor prefers to avoid concurrency optimizations like using `futures::future::try_join_all` for parallel processing of balance changes, considering such optimizations "not that critical at the moment" when the performance impact is minimal.
Learnt from: brusherru
Repo: rainlanguage/rain.orderbook PR: 2044
File: tauri-app/src/routes/orders/[chainId]-[orderbook]-[orderHash]/+page.svelte:76-78
Timestamp: 2025-07-31T19:03:56.594Z
Learning: In the rainlanguage/rain.orderbook project, when the Tauri app has issues preventing proper testing, the team prefers to defer Tauri-specific implementations to separate PRs rather than including untested code, especially for financial operations like withdrawals.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1956
File: crates/common/src/raindex_client/orders.rs:609-609
Timestamp: 2025-07-04T10:27:22.544Z
Learning: In the rainlanguage/rain.orderbook codebase, user findolor prefers not to implement overflow protection for trades count casting (usize to u16) at this time, considering it unnecessary for the current scope since the practical risk of orders having 65,535+ trades is extremely low.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1956
File: crates/common/src/fuzz/mod.rs:64-64
Timestamp: 2025-07-04T09:02:57.301Z
Learning: In rainlanguage/rain.orderbook, user findolor prefers to limit type consistency changes to only the parts directly related to the current work scope. For example, when updating chain_id fields from u64 to u32 in fuzz-related code, unrelated files like tauri-app wallet commands can remain as u64 if they serve different purposes and aren't part of the current changes.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1872
File: packages/webapp/src/lib/services/handleVaultWithdraw.ts:50-54
Timestamp: 2025-06-07T05:19:04.767Z
Learning: In the rainlanguage/rain.orderbook codebase, the team prefers pragmatic code approaches over strict TypeScript patterns when the current implementation is sufficient for their use case, such as using `if (result.error)` instead of `if ('error' in result)` for discriminated union type checking.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1938
File: crates/js_api/src/raindex/mod.rs:102-118
Timestamp: 2025-06-18T12:56:44.290Z
Learning: In the rainlanguage/rain.orderbook codebase, it's acceptable to scaffold unused enum variants in initial implementation PRs when they will be implemented in future PRs, as confirmed by findolor.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 1938
File: crates/js_api/src/raindex/orders.rs:1-11
Timestamp: 2025-06-18T12:54:47.807Z
Learning: In the rain.orderbook repository, findolor prefers to keep unused imports in place when they will be used in upcoming follow-up PRs, rather than removing and re-adding them during incremental development.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2155
File: crates/common/src/raindex_client/trades.rs:133-152
Timestamp: 2025-10-06T14:13:18.531Z
Learning: In the rain.orderbook codebase, the `page` parameter in `RaindexOrder::get_trades_list` method (in crates/common/src/raindex_client/trades.rs) is kept for backwards compatibility with subgraph logic, but the LocalDb fast-path intentionally returns all trades without implementing pagination.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2001
File: crates/common/src/raindex_client/order_quotes.rs:62-69
Timestamp: 2025-07-16T14:33:13.457Z
Learning: In the rainlanguage/rain.orderbook codebase, findolor considers hardcoded decimal values (18 and 36) in order quote formatting logic to be acceptable for their use case, even when dynamic token decimals could theoretically provide more accurate formatting for different tokens.
Learnt from: findolor
Repo: rainlanguage/rain.orderbook PR: 2099
File: crates/common/src/raindex_client/sqlite_web/fetch.rs:128-133
Timestamp: 2025-08-26T11:19:30.219Z
Learning: In the rain.orderbook codebase, deterministic ordering with tie-breakers (transactionIndex, logIndex) within the same block is not required when sorting events. Block-level sorting is sufficient for the project's needs.
Motivation
See issues:
The Local DB sync scheduler previously ran all configured networks in a single sync cycle. This meant one slow or failing network (RPC timeouts, rate limiting, etc.) could block healthy networks from progressing, resulting in poor UX and preventing timely updates on healthy networks.
Solution
Refactored the Local DB sync scheduler to run each network on an independent sync cycle:
Rust changes (
crates/common/src/raindex_client/local_db/):NetworkRunnerConfigto filter global settings per network and build network-specific targetsNetworkSyncStatusstruct with network-aware status fields (networkKey,chainId,status,schedulerState,error)SchedulerStateenum (Leader/NotLeader) to indicate leadership status per networkSchedulerHandleto track network keys and use synchronous stop (no longer async)from_configconstructor toClientRunnerfor per-network configurationwith_network_keyconstructor for per-network lock managementWebapp changes (
packages/webapp/):localDbStatus.tsstore to maintain aMap<string, NetworkSyncStatus>for per-network statusupdateNetworkStatusfunction to update individual network statusesaggregateStatusderived store that computes overall status from per-network statusesupdateNetworkStatuscallback patternKey behaviors:
Checks
By submitting this for review, I'm confirming I've done the following:
fix #2378
Summary by CodeRabbit
New Features
Refactor
Other
✏️ Tip: You can customize this high-level summary in your review settings.