diff --git a/CHANGELOG.md b/CHANGELOG.md index eb58e05a..e4cfeb1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. --- -## [v0.2.0] - 2025-12-11 [βœ… Released] +## [v0.2.0] - 2026-01-01 [βœ… Released] ### 🎯 Highlights for Developers diff --git a/Cargo.lock b/Cargo.lock index 27469860..0757e827 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -595,10 +595,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "d-engine-docs" -version = "0.2.0" - [[package]] name = "d-engine-proto" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index 7a63c446..32d0b718 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,13 +4,12 @@ members = [ "d-engine-proto", "d-engine-core", "d-engine-client", - "d-engine-docs", "d-engine-server" ] exclude = [ + "docs", "examples/client_usage", - "examples/rocksdb-cluster", "examples/sled-cluster", "examples/three-nodes-cluster", "examples/single-node-expansion", @@ -32,10 +31,10 @@ repository = "https://github.com/deventlab/d-engine" license = "MIT OR Apache-2.0" [workspace.dependencies] -d-engine-proto = { path = "./d-engine-proto" } -d-engine-core = { path = "./d-engine-core" } -d-engine-client = { path = "./d-engine-client" } -d-engine-server = { path = "./d-engine-server" } +d-engine-proto = { path = "./d-engine-proto", version = "0.2.0" } +d-engine-core = { path = "./d-engine-core", version = "0.2.0" } +d-engine-client = { path = "./d-engine-client", version = "0.2.0" } +d-engine-server = { path = "./d-engine-server", version = "0.2.0" } tokio = { version = "1", features = [ "macros", diff --git a/Makefile b/Makefile index 69b1a196..0127435e 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ RUST_LOG_LEVEL ?= d_engine_server=debug,d_engine_core=debug,d_engine_client=debu RUST_BACKTRACE ?= 1 # Workspace member crates -WORKSPACE_MEMBERS := d-engine-proto d-engine-core d-engine-client d-engine-server d-engine-docs d-engine +WORKSPACE_MEMBERS := d-engine-proto d-engine-core d-engine-client d-engine-server d-engine # Color codes for formatted output RED := \033[0;31m @@ -382,19 +382,19 @@ bench-gate: check-workspace ## docs Generate API documentation and open in browser (opens d-engine API hub) docs: check-workspace @echo "$(BLUE)Generating API documentation for public crates...$(NC)" - @$(CARGO) doc --package d-engine --package d-engine-docs --no-deps \ + @$(CARGO) doc --package d-engine --no-deps \ --features "d-engine/client,d-engine/server,d-engine/rocksdb,d-engine/watch" @echo "$(GREEN)βœ“ Documentation generated$(NC)" - @echo "$(CYAN)Opening documentation hub at: target/doc/d_engine_docs/index.html$(NC)" - @open "file://$$(pwd)/target/doc/d_engine_docs/index.html" 2>/dev/null || xdg-open "file://$$(pwd)/target/doc/d_engine_docs/index.html" 2>/dev/null || echo "Please open: target/doc/d_engine_docs/index.html" + @echo "$(CYAN)Opening documentation at: target/doc/d_engine/index.html$(NC)" + @open "file://$$(pwd)/target/doc/d_engine/index.html" 2>/dev/null || xdg-open "file://$$(pwd)/target/doc/d_engine/index.html" 2>/dev/null || true ## docs-all Generate documentation with all features enabled docs-all: check-workspace @echo "$(BLUE)Generating API documentation (all features)...$(NC)" @$(CARGO) doc --workspace --all-features --no-deps @echo "$(GREEN)βœ“ Documentation generated$(NC)" - @echo "$(CYAN)Opening documentation hub at: target/doc/d_engine_docs/index.html$(NC)" - @open "file://$$(pwd)/target/doc/d_engine_docs/index.html" 2>/dev/null || xdg-open "file://$$(pwd)/target/doc/d_engine_docs/index.html" 2>/dev/null || echo "Please open: target/doc/d_engine_docs/index.html" + @echo "$(CYAN)Opening documentation at: target/doc/d_engine/index.html$(NC)" + @open "file://$$(pwd)/target/doc/d_engine/index.html" 2>/dev/null || xdg-open "file://$$(pwd)/target/doc/d_engine/index.html" 2>/dev/null || true ## docs-check Check documentation without opening browser (CI-safe) docs-check: check-workspace diff --git a/README.md b/README.md index 69d4f8e5..fc69b22c 100644 --- a/README.md +++ b/README.md @@ -12,26 +12,6 @@ with pluggable storage backends, built-in observability, and tokio runtime suppo --- -## 🚧 Project Status - -d-engine is in **active development** (pre-1.0). - -**For Production Use**: - -- βœ… Core Raft consensus is stable (1000+ integration tests, Jepsen validated) -- βœ… API surface is stabilizing (v0.2.0 focuses on developer experience) -- ⚠️ Pre-1.0: Breaking changes may occur between minor versions (e.g., v0.2 β†’ v0.3) -- πŸ“‹ [Semantic Versioning](https://semver.org/) will strictly apply after v1.0 - -**Compatibility Promise**: - -- **Before v1.0**: Breaking changes documented in [MIGRATION_GUIDE.md](./MIGRATION_GUIDE.md) -- **After v1.0**: Breaking changes only in major versions (v1.x β†’ v2.0) - -**Current Focus**: API stabilization for v1.0 release (Q2 2026) - ---- - ## Features ### New in v0.2.0 πŸŽ‰ diff --git a/benches/d-engine-bench/README.md b/benches/d-engine-bench/README.md index 1f721828..819d08f2 100644 --- a/benches/d-engine-bench/README.md +++ b/benches/d-engine-bench/README.md @@ -12,7 +12,7 @@ Ensure you're using the correct d-engine version in your `Cargo.toml`: ```toml [dependencies] -d-engine = "0.1.2" # Verify latest version +d-engine = "0.2.0" # Verify latest version ``` ### 2. Setup Cluster diff --git a/benches/d-engine-bench/reports/v0.2.0/report_v0.2.0_final.md b/benches/d-engine-bench/reports/v0.2.0/report_v0.2.0_final.md index 8f371667..638fb574 100644 --- a/benches/d-engine-bench/reports/v0.2.0/report_v0.2.0_final.md +++ b/benches/d-engine-bench/reports/v0.2.0/report_v0.2.0_final.md @@ -8,7 +8,7 @@ - ⚠️ **Read**: etcd 11.7x faster in linearizable reads (hardware difference) - βœ… **Unique**: LeaseRead provides 6.9x performance vs linearizable with strong consistency -**vs v0.1.4**: +**vs v0.2.0**: - βœ… **All scenarios improved** 2.3% to 11% throughput - βœ… **LeaseRead p99**: -44% latency (7.87ms vs 14.05ms) - biggest win diff --git a/d-engine-client/Cargo.toml b/d-engine-client/Cargo.toml index 017d19dc..b2ad8139 100644 --- a/d-engine-client/Cargo.toml +++ b/d-engine-client/Cargo.toml @@ -3,13 +3,13 @@ name = "d-engine-client" version.workspace = true edition.workspace = true authors.workspace = true -description = "Client library for connecting to d-engine Raft consensus servers" +description = "Client library for interacting with d-engine Raft clusters via gRPC" homepage.workspace = true repository.workspace = true license.workspace = true keywords = ["raft", "consensus", "client", "async"] categories = ["asynchronous", "network-programming"] -publish = false +publish = true [package.metadata.docs.rs] all-features = true diff --git a/d-engine-client/README.md b/d-engine-client/README.md new file mode 100644 index 00000000..2de5e556 --- /dev/null +++ b/d-engine-client/README.md @@ -0,0 +1,43 @@ +# d-engine-client + +[![Crates.io](https://img.shields.io/crates/v/d-engine-client.svg)](https://crates.io/crates/d-engine-client) +[![docs.rs](https://docs.rs/d-engine-client/badge.svg)](https://docs.rs/d-engine-client) + +Client library for interacting with d-engine Raft clusters + +--- + +## ⚠️ You Probably Don't Need This Crate + +**Use [`d-engine`](https://crates.io/crates/d-engine) instead:** + +```toml +[dependencies] +d-engine = { version = "0.2", features = ["client"] } +``` + +This provides the same API with simpler dependency management. The `d-engine-client` crate is automatically included when you enable the `client` feature. + +--- + +## For Contributors + +This crate exists for architectural reasons: + +- **Clean boundaries** - Separates client logic from server implementation +- **Faster builds** - Workspace members can depend on client without pulling server deps +- **Testing** - Enables isolated client testing + +If you're building an application, use `d-engine` with `features = ["client"]` instead. + +--- + +## Quick Reference + +See [`d-engine` README](https://github.com/deventlab/d-engine/blob/main/README.md) for usage examples and documentation. + +--- + +## License + +MIT or Apache-2.0 diff --git a/d-engine-client/src/lib.rs b/d-engine-client/src/lib.rs index 76a45975..47d2b70a 100644 --- a/d-engine-client/src/lib.rs +++ b/d-engine-client/src/lib.rs @@ -1,46 +1,68 @@ -//! Client module for distributed consensus system +//! # d-engine-client //! -//! Provides core components for interacting with the d_engine cluster: -//! - [`Client`] - Main entry point with cluster access -//! - [`ClientBuilder`] - Configurable client construction -//! - [`KvClient`] - Key-value store operations -//! - [`ClusterClient`] - Cluster management operations -//! - [`ConnectionPool`] - Underlying connection management +//! Client library for interacting with d-engine Raft clusters via gRPC +//! +//! ## ⚠️ You Probably Don't Need This Crate +//! +//! **Use [`d-engine`](https://crates.io/crates/d-engine) instead:** +//! +//! ```toml +//! [dependencies] +//! d-engine = { version = "0.2", features = ["client"] } +//! ``` +//! +//! This provides the same API with simpler dependency management. The `d-engine-client` crate +//! is automatically included when you enable the `client` feature. +//! +//! ## For Contributors //! -//! # Basic Usage -//! ```no_run +//! This crate exists for architectural reasons: +//! - Clean boundaries between client and server +//! - Faster builds during development +//! - Isolated client testing +//! +//! ## Quick Start +//! +//! ```rust,ignore //! use d_engine_client::Client; -//! use d_engine_client::ClientBuilder; -//! use std::time::Duration; -//! use core::error::Error; -//! -//! #[tokio::main(flavor = "current_thread")] -//! async fn main(){ -//! // Initialize client with automatic cluster discovery -//! let client = Client::builder(vec![ -//! "http://node1:9081".into(), -//! "http://node2:9082".into() -//! ]) -//! .connect_timeout(Duration::from_secs(3)) -//! .request_timeout(Duration::from_secs(1)) -//! .enable_compression(true) -//! .build() -//! .await -//! .unwrap(); -//! -//! // Execute key-value operations -//! client.kv().put("user:1001", "Alice").await.unwrap(); -//! -//! let value = client.kv().get("user:1001").await.unwrap(); -//! -//! println!("User data: {:?}", value); -//! -//! // Perform cluster management -//! let members = client.cluster().list_members().await.unwrap(); -//! println!("Cluster members: {:?}", members); //! +//! #[tokio::main] +//! async fn main() -> Result<(), Box> { +//! let client = Client::connect(vec!["http://localhost:50051"]).await?; +//! +//! // Write data +//! client.put(b"key".to_vec(), b"value".to_vec()).await?; +//! +//! // Read data +//! if let Some(value) = client.get(b"key".to_vec()).await? { +//! println!("Value: {:?}", value); +//! } +//! +//! Ok(()) //! } //! ``` +//! +//! ## Read Consistency +//! +//! Choose consistency level based on your needs: +//! +//! - `get_linearizable()` - Strong consistency (read from Leader) +//! - `get_eventual()` - Fast local reads (stale OK) +//! - `get_lease()` - Optimized with leader lease +//! +//! ## Features +//! +//! This crate provides: +//! - [`Client`] - Main entry point with cluster access +//! - [`ClientBuilder`] - Configurable client construction +//! - [`KvClient`] - Key-value store operations trait +//! - [`ClusterClient`] - Cluster management operations +//! +//! ## Documentation +//! +//! For comprehensive guides: +//! - [Read Consistency](https://docs.rs/d-engine/latest/d_engine/docs/client_guide/read_consistency/index.html) +//! - [Error Handling](https://docs.rs/d-engine/latest/d_engine/docs/client_guide/error_handling/index.html) mod builder; mod cluster; diff --git a/d-engine-core/Cargo.toml b/d-engine-core/Cargo.toml index 215e754d..c83cc088 100644 --- a/d-engine-core/Cargo.toml +++ b/d-engine-core/Cargo.toml @@ -3,13 +3,13 @@ name = "d-engine-core" version.workspace = true edition.workspace = true authors.workspace = true -description = "Core Raft consensus algorithm implementation and traits" +description = "Pure Raft consensus algorithm - for building custom Raft-based systems" homepage.workspace = true repository.workspace = true license.workspace = true keywords = ["raft", "consensus", "algorithm"] categories = ["algorithms", "concurrency"] -publish = false +publish = true [package.metadata.docs.rs] all-features = true diff --git a/d-engine-core/README.md b/d-engine-core/README.md new file mode 100644 index 00000000..9de69d74 --- /dev/null +++ b/d-engine-core/README.md @@ -0,0 +1,69 @@ +# d-engine-core + +[![Crates.io](https://img.shields.io/crates/v/d-engine-core.svg)](https://crates.io/crates/d-engine-core) +[![docs.rs](https://docs.rs/d-engine-core/badge.svg)](https://docs.rs/d-engine-core) + +Pure Raft consensus algorithm - for building custom Raft-based systems + +--- + +## ⚠️ Internal Crate - Not Ready for Standalone Use + +**Use [`d-engine`](https://crates.io/crates/d-engine) instead.** + +This crate contains the pure Raft consensus algorithm used internally by d-engine. The API is unstable before v1.0. + +```toml +# ❌ Don't use this directly +[dependencies] +d-engine-core = "0.2" + +# βœ… Use this instead +[dependencies] +d-engine = "0.2" +``` + +--- + +## For Contributors + +This crate provides the core Raft consensus algorithm: + +- **Leader Election** - Automatic leader election with randomized timeouts +- **Log Replication** - Reliable log replication to followers +- **Membership Changes** - Dynamic cluster membership (add/remove nodes) +- **Snapshot Support** - Log compaction via snapshots + +**Reference integration**: See how [d-engine-server](https://github.com/deventlab/d-engine/tree/main/d-engine-server) uses this crate. + +**Key traits to understand**: + +- `StorageEngine` - Persistent storage for Raft logs +- `StateMachine` - Application-specific state transitions +- `LogStore` - Log entry persistence +- `MetaStore` - Metadata persistence (term, voted_for) + +See the [API documentation](https://docs.rs/d-engine-core) for detailed trait definitions. + +--- + +## Future Vision + +**Post-1.0 goal**: Become a standalone Raft library with stable API. + +**Current status**: Internal to d-engine, API may change between minor versions. + +--- + +## Documentation + +For understanding d-engine internals: + +- [Customize Storage Engine](https://docs.rs/d-engine/latest/d_engine/docs/server_guide/customize_storage_engine/index.html) +- [Customize State Machine](https://docs.rs/d-engine/latest/d_engine/docs/server_guide/customize_state_machine/index.html) + +--- + +## License + +MIT or Apache-2.0 diff --git a/d-engine-core/src/lib.rs b/d-engine-core/src/lib.rs index 20132e62..5e2de75c 100644 --- a/d-engine-core/src/lib.rs +++ b/d-engine-core/src/lib.rs @@ -1,3 +1,58 @@ +//! # d-engine-core +//! +//! Pure Raft consensus algorithm - for building custom Raft-based systems +//! +//! ## ⚠️ Internal Crate - Not Ready for Standalone Use +//! +//! **Use [`d-engine`](https://crates.io/crates/d-engine) instead.** +//! +//! This crate contains the pure Raft consensus algorithm used internally by d-engine. +//! The API is unstable before v1.0. +//! +//! ```toml +//! # ❌ Don't use this directly +//! [dependencies] +//! d-engine-core = "0.2" +//! +//! # βœ… Use this instead +//! [dependencies] +//! d-engine = "0.2" +//! ``` +//! +//! ## For Contributors +//! +//! ## What this crate provides +//! +//! This crate focuses solely on the Raft consensus algorithm: +//! +//! - **Leader Election** - Automatic leader election with randomized timeouts +//! - **Log Replication** - Reliable log replication to followers +//! - **Membership Changes** - Dynamic cluster membership changes +//! - **Snapshot Support** - Log compaction via snapshots +//! +//! Storage, networking, and state machine implementation are **your responsibility**. +//! +//! **Reference integration**: See how [d-engine-server](https://github.com/deventlab/d-engine/tree/main/d-engine-server) uses this crate. +//! +//! ## Future Vision +//! +//! **Post-1.0 goal**: Become a standalone Raft library with stable API. +//! +//! **Current status**: Internal to d-engine, API may change between minor versions. +//! +//! ## Key Traits +//! +//! - [`StorageEngine`] - Persistent storage for Raft logs +//! - [`StateMachine`] - Application-specific state transitions +//! - [`LogStore`] - Log entry persistence +//! - [`MetaStore`] - Metadata persistence (term, voted_for) +//! +//! ## Documentation +//! +//! For comprehensive guides: +//! - [Customize Storage Engine](https://docs.rs/d-engine/latest/d_engine/docs/server_guide/customize_storage_engine/index.html) +//! - [Customize State Machine](https://docs.rs/d-engine/latest/d_engine/docs/server_guide/customize_state_machine/index.html) + mod commit_handler; pub mod config; mod election; diff --git a/d-engine-core/src/storage/state_machine.rs b/d-engine-core/src/storage/state_machine.rs index b4e14c15..e2bc1935 100644 --- a/d-engine-core/src/storage/state_machine.rs +++ b/d-engine-core/src/storage/state_machine.rs @@ -1,4 +1,4 @@ -#![doc = include_str!("../../../d-engine-docs/src/docs/server_guide/customize-state-machine.md")] +#![doc = include_str!("../../../d-engine/src/docs/server_guide/customize-state-machine.md")] use bytes::Bytes; use d_engine_proto::common::Entry; diff --git a/d-engine-core/src/storage/storage_engine.rs b/d-engine-core/src/storage/storage_engine.rs index a94b6ed0..d5ad034c 100644 --- a/d-engine-core/src/storage/storage_engine.rs +++ b/d-engine-core/src/storage/storage_engine.rs @@ -1,4 +1,4 @@ -#![doc = include_str!("../../../d-engine-docs/src/docs/server_guide/customize-storage-engine.md")] +#![doc = include_str!("../../../d-engine/src/docs/server_guide/customize-storage-engine.md")] use std::ops::RangeInclusive; use std::sync::Arc; diff --git a/d-engine-docs/Cargo.toml b/d-engine-docs/Cargo.toml deleted file mode 100644 index f96a927d..00000000 --- a/d-engine-docs/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "d-engine-docs" -version.workspace = true -edition.workspace = true -authors.workspace = true -description = "Documentation and guides for d-engine Raft consensus engine" -homepage.workspace = true -repository.workspace = true -license.workspace = true -keywords = ["raft", "consensus", "documentation"] -categories = ["documentation"] -publish = true - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = ["--cfg", "docsrs"] - -[dependencies] -# No dependencies needed - this is a pure documentation crate diff --git a/d-engine-docs/src/lib.rs b/d-engine-docs/src/lib.rs deleted file mode 100644 index 39c84358..00000000 --- a/d-engine-docs/src/lib.rs +++ /dev/null @@ -1,96 +0,0 @@ -#![warn(missing_docs)] - -//! # d-engine - Distributed Coordination Engine -//! -//! **d-engine** is a lightweight distributed coordination engine written in Rust, designed for -//! embedding into applications that need strong consistencyβ€”the consensus layer for building -//! reliable distributed systems. -//! -//! ## πŸš€ New to d-engine? Start Here -//! -//! Follow this learning path to get started quickly: -//! -//! ```text -//! 1. Is d-engine Right for You? (1 minute) -//! ↓ -//! 2. Choose Integration Mode (1 minute) -//! ↓ -//! 3a. Quick Start - Embedded (5 minutes) -//! OR -//! 3b. Quick Start - Standalone (5 minutes) -//! ↓ -//! 4. Scale to Cluster (optional) -//! ``` -//! -//! **β†’ Start: [Is d-engine Right for You?](docs::use_cases)** -//! -//! ## Crate Organization -//! -//! | Crate | Purpose | -//! |-------|---------| -//! | **d-engine-proto** | Protocol definitions (Prost) | -//! | **d-engine-core** | Core Raft algorithm & traits | -//! | **d-engine-client** | Client library for applications | -//! | **d-engine-server** | Server runtime implementation | -//! | **d-engine-docs** | Documentation (you are here) | -//! -//! ## Quick Start -//! -//! ### Embedded Mode (Rust) -//! -//! ```rust,ignore -//! use d_engine::prelude::*; -//! -//! #[tokio::main] -//! async fn main() -> Result<(), Box> { -//! let engine = EmbeddedEngine::with_rocksdb("./data", None).await?; -//! engine.wait_ready(std::time::Duration::from_secs(5)).await?; -//! -//! let client = engine.client(); -//! client.put(b"key".to_vec(), b"value".to_vec()).await?; -//! -//! Ok(()) -//! } -//! ``` -//! -//! **β†’ [5-Minute Embedded Guide](docs::quick_start_5min)** -//! -//! ### Standalone Mode (Any Language) -//! -//! ```bash -//! cd examples/three-nodes-cluster -//! make start-cluster -//! ``` -//! -//! **β†’ [Standalone Guide](docs::quick_start_standalone)** -//! -//! ## Documentation Index -//! -//! ### Getting Started -//! - [Is d-engine Right for You?](docs::use_cases) - Common use cases -//! - [Integration Modes](docs::integration_modes) - Embedded vs Standalone -//! - [Quick Start - Embedded](docs::quick_start_5min) -//! - [Quick Start - Standalone](docs::quick_start_standalone) -//! -//! ### Guides by Role -//! -//! #### Client Developers -//! - [Read Consistency](docs::client_guide::read_consistency) - Choosing consistency policies -//! - [Error Handling](docs::client_guide::error_handling) -//! -//! #### Server Operators -//! - [Customize Storage Engine](docs::server_guide::customize_storage_engine) -//! - [Customize State Machine](docs::server_guide::customize_state_machine) -//! - [Consistency Tuning](docs::server_guide::consistency_tuning) -//! - [Watch Feature](docs::server_guide::watch_feature) -//! -//! ### Examples & Performance -//! - [Single Node Expansion](docs::examples::single_node_expansion) - Scale from 1 to 3 nodes -//! - [Throughput Optimization](docs::performance::throughput_optimization_guide) -//! -//! -//! ## License -//! -//! MIT or Apache-2.0 - -pub mod docs; diff --git a/d-engine-proto/Cargo.toml b/d-engine-proto/Cargo.toml index 26aa95c8..e747f80e 100644 --- a/d-engine-proto/Cargo.toml +++ b/d-engine-proto/Cargo.toml @@ -3,13 +3,13 @@ name = "d-engine-proto" version.workspace = true edition.workspace = true authors.workspace = true -description = "Protocol definitions and message types for d-engine using Prost" +description = "gRPC protocol definitions - for building non-Rust d-engine clients" homepage.workspace = true repository.workspace = true license.workspace = true keywords = ["raft", "protobuf", "grpc"] categories = ["encoding", "network-programming"] -publish = false +publish = true [package.metadata.docs.rs] all-features = true diff --git a/d-engine-proto/README.md b/d-engine-proto/README.md new file mode 100644 index 00000000..012a46d8 --- /dev/null +++ b/d-engine-proto/README.md @@ -0,0 +1,122 @@ +# d-engine-proto + +[![Crates.io](https://img.shields.io/crates/v/d-engine-proto.svg)](https://crates.io/crates/d-engine-proto) +[![docs.rs](https://docs.rs/d-engine-proto/badge.svg)](https://docs.rs/d-engine-proto) + +gRPC protocol definitions for d-engine - foundation for all client implementations + +--- + +## What is this? + +This crate contains the Protocol Buffer definitions and generated Rust code for d-engine's gRPC API. It's the foundation for building clients in **any programming language** that supports gRPC. + +**d-engine** is a lightweight distributed coordination engine written in Rust, designed for embedding into applications that need strong consistencyβ€”the consensus layer for building reliable distributed systems. + +--- + +## When to use this crate + +- βœ… Building **non-Rust clients** (Python/Go/C#) for d-engine clusters +- βœ… Need raw `.proto` files for code generation +- βœ… Contributing to d-engine protocol development +- βœ… Implementing custom protocol extensions + +--- + +## When NOT to use this crate + +- ❌ **Writing Rust applications** β†’ Use [`d-engine`](https://crates.io/crates/d-engine) or [`d-engine-client`](https://crates.io/crates/d-engine-client) for higher-level APIs +- ❌ **Need a working client immediately** β†’ See language-specific client libraries (coming soon) + +--- + +## Quick Start + +### For Non-Rust Developers + +**Step 1: Get the proto files** + +Clone the d-engine repository or download the proto files: + +```bash +git clone https://github.com/deventlab/d-engine.git +cd d-engine/d-engine-proto +``` + +**Step 2: Generate client code** + +```bash +# Go example (βœ… Tested - see https://github.com/deventlab/d-engine/tree/main/examples/quick-start-standalone) +protoc -I. \ + --go_out=./go \ + --go_opt=module=github.com/deventlab/d-engine/proto \ + --go-grpc_out=./go \ + --go-grpc_opt=module=github.com/deventlab/d-engine/proto \ + proto/common.proto \ + proto/error.proto \ + proto/client/client_api.proto + +# Python example (⚠️ Command verified, end-to-end integration not yet tested) +protoc --python_out=./out \ + proto/common.proto \ + proto/error.proto \ + proto/client/client_api.proto +``` + +**Language Support Status:** + +- βœ… **Go** - Production-ready with [working example](https://github.com/deventlab/d-engine/tree/main/examples/quick-start-standalone) +- ⚠️ **Python** - Proto generation verified, client integration pending +- πŸ”œ **Other languages** - Community contributions welcome + +**Note:** + +- Commands assume you're in the `d-engine-proto` directory +- The proto files have dependencies - always include `common.proto` and `error.proto` when generating client code +- For Go: adjust `module=` option to match your project's module path + +### For Rust Developers + +```toml +# Don't use this directly - use the high-level crates instead +[dependencies] +d-engine = { version = "0.2", features = ["client"] } +``` + +--- + +## Protocol Structure + +This crate provides protobuf-generated types organized by service area: + +- **`common`** - Core Raft types (LogId, Entry, etc.) +- **`error`** - Error types and metadata +- **`client`** - Client request/response types +- **`server`** - Server-to-server communication types + +--- + +## Documentation + +For language-specific integration guides: + +- [Go Client Example](https://github.com/deventlab/d-engine/tree/main/examples/quick-start-standalone) +- [Error Handling](https://docs.rs/d-engine/latest/d_engine/docs/client_guide/error_handling/index.html) + +--- + +## Related Crates + +| Crate | Purpose | +| ------------------------------------------------------------- | ------------------------------------------- | +| [`d-engine`](https://crates.io/crates/d-engine) | **Recommended** - Unified API for Rust apps | +| [`d-engine-client`](https://crates.io/crates/d-engine-client) | High-level Rust client library | +| [`d-engine-server`](https://crates.io/crates/d-engine-server) | Server implementation | +| [`d-engine-core`](https://crates.io/crates/d-engine-core) | Pure Raft algorithm | + +--- + +## License + +MIT or Apache-2.0 diff --git a/d-engine-proto/src/lib.rs b/d-engine-proto/src/lib.rs index f8068e77..3cc1ec92 100644 --- a/d-engine-proto/src/lib.rs +++ b/d-engine-proto/src/lib.rs @@ -1,8 +1,62 @@ -//! Protocol buffer type extensions +//! # d-engine-proto //! -//! This module provides additional trait implementations and helper methods -//! for protobuf-generated types. The re-exports here are used by dependent crates -//! (d-engine-core, d-engine, d-engine-client) when they import from this crate. +//! gRPC protocol definitions for d-engine - foundation for all client implementations +//! +//! ## When to use this crate +//! +//! - βœ… Building Go/Python/Java clients +//! - βœ… Need raw `.proto` files for code generation +//! - βœ… Custom protocol extensions +//! - βœ… Contributing to d-engine protocol development +//! +//! ## For Rust users +//! +//! If you're writing Rust code, use [`d-engine`](https://crates.io/crates/d-engine) or +//! [`d-engine-client`](https://crates.io/crates/d-engine-client) instead - they provide +//! higher-level APIs on top of these protocol definitions. +//! +//! ```toml +//! [dependencies] +//! d-engine = { version = "0.2", features = ["client"] } +//! ``` +//! +//! ## For Non-Rust Developers +//! +//! The `.proto` files are included in this crate. Generate client code for your language: +//! +//! ```bash +//! # Go (βœ… Tested - see examples/quick-start-standalone) +//! protoc -I. \ +//! --go_out=./go \ +//! --go_opt=module=github.com/deventlab/d-engine/proto \ +//! --go-grpc_out=./go \ +//! --go-grpc_opt=module=github.com/deventlab/d-engine/proto \ +//! proto/common.proto \ +//! proto/error.proto \ +//! proto/client/client_api.proto +//! +//! # Python (⚠️ Command verified, end-to-end integration not yet tested) +//! protoc --python_out=./out \ +//! proto/common.proto \ +//! proto/error.proto \ +//! proto/client/client_api.proto +//! ``` +//! +//! **Language Support Status:** +//! - βœ… **Go** - Production-ready with working example +//! - ⚠️ **Python** - Proto generation verified, client integration pending +//! - πŸ”œ **Other languages** - Community contributions welcome +//! +//! Protocol files are located in the source repository under `d-engine-proto/proto/`. +//! +//! ## Documentation +//! +//! For language-specific integration guides: +//! - [Go Client Example](https://github.com/deventlab/d-engine/tree/main/examples/quick-start-standalone) +//! +//! ## Protocol Modules +//! +//! This crate provides protobuf-generated Rust types organized by service area: pub mod common { include!("generated/d_engine.common.rs"); diff --git a/d-engine-server/Cargo.toml b/d-engine-server/Cargo.toml index e92e4e47..06c62a25 100644 --- a/d-engine-server/Cargo.toml +++ b/d-engine-server/Cargo.toml @@ -9,7 +9,7 @@ repository.workspace = true license.workspace = true keywords = ["raft", "consensus", "distributed-systems", "async"] categories = ["asynchronous", "concurrency", "network-programming"] -publish = false +publish = true [package.metadata.docs.rs] all-features = true diff --git a/d-engine-server/README.md b/d-engine-server/README.md index fbe5d884..4c0c8752 100644 --- a/d-engine-server/README.md +++ b/d-engine-server/README.md @@ -1,151 +1,147 @@ # d-engine-server -Production-ready Raft consensus server implementation. Provides strongly-consistent distributed key-value storage with pluggable backends. +[![Crates.io](https://img.shields.io/crates/v/d-engine-server.svg)](https://crates.io/crates/d-engine-server) +[![docs.rs](https://docs.rs/d-engine-server/badge.svg)](https://docs.rs/d-engine-server) -## What is d-engine-server? +Complete Raft server with gRPC and storage - batteries included -d-engine-server is the server runtime for d-engine - it combines: +--- -- **Raft consensus protocol** (from d-engine-core) -- **gRPC networking** for cluster communication -- **Pluggable storage backends** (File, RocksDB) -- **State machine** for executing client commands +## What is this? -Think of it as: **Raft protocol + Storage + Network = Running Server** +This crate provides a **complete Raft server implementation** with gRPC networking, persistent storage, and cluster orchestration. It's the server runtime component of d-engine. -## Architecture - -``` -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ d-engine-server β”‚ -β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ Node (Raft node lifecycle) β”‚ β”‚ -β”‚ β”‚ - Leader election β”‚ β”‚ -β”‚ β”‚ - Log replication β”‚ β”‚ -β”‚ β”‚ - Cluster membership β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ StorageEngine β”‚ β”‚ StateMachine β”‚ β”‚ -β”‚ β”‚ - Log storage β”‚ β”‚ - Apply commands β”‚ β”‚ -β”‚ β”‚ - Metadata β”‚ β”‚ - Snapshots β”‚ β”‚ -β”‚ β”‚ - HardState β”‚ β”‚ - KV operations β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β”‚ β”‚ -β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ -β”‚ β”‚ gRPC Services β”‚ β”‚ -β”‚ β”‚ - RaftClientService (client read/write) β”‚ β”‚ -β”‚ β”‚ - RaftService (peer-to-peer replication) β”‚ β”‚ -β”‚ β”‚ - RaftClusterService (membership changes) β”‚ β”‚ -β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` +**d-engine** is a lightweight distributed coordination engine written in Rust, designed for embedding into applications that need strong consistencyβ€”the consensus layer for building reliable distributed systems. -### Key Components +--- -**Node** - The Raft consensus participant +## When to use this crate -- Manages node lifecycle (follower β†’ candidate β†’ leader) -- Coordinates log replication across cluster -- Handles client requests and membership changes +- βœ… **Embedding server** in a larger Rust application +- βœ… Need **programmatic access** to server APIs +- βœ… Building **custom tooling** around d-engine +- βœ… Already have your own client implementation -**StorageEngine** - Persistent storage for Raft state +--- -- `LogStore`: Raft log entries -- `MetaStore`: Term, voted_for, commit_index +## When NOT to use this crate -**StateMachine** - Application state executor +- ❌ **Most applications** β†’ Use [`d-engine`](https://crates.io/crates/d-engine) for simpler dependency management +- ❌ **Need client + server** β†’ Use [`d-engine`](https://crates.io/crates/d-engine) with `features = ["server", "client"]` +- ❌ **Quick start preferred** β†’ Use [`d-engine`](https://crates.io/crates/d-engine) for unified API -- Applies committed log entries to KV store -- Generates snapshots for log compaction -- Restores state from snapshots +--- ## Quick Start -### 1. Single Node (Development) +Add to your `Cargo.toml`: + +```toml +[dependencies] +d-engine-server = "0.2" +``` + +### Embedded Mode (zero-overhead local client) ```rust -use d_engine_server::{NodeBuilder, FileStorageEngine, FileStateMachine}; -use std::sync::Arc; -use std::path::PathBuf; +use d_engine_server::EmbeddedEngine; +use std::time::Duration; #[tokio::main] async fn main() -> Result<(), Box> { - let (shutdown_tx, shutdown_rx) = tokio::sync::watch::channel(()); - - // Create storage components - let storage = Arc::new( - FileStorageEngine::new(PathBuf::from("/tmp/raft-log"))? - ); - let state_machine = Arc::new( - FileStateMachine::new(PathBuf::from("/tmp/raft-sm")).await? - ); - - // Build and start node - let node = NodeBuilder::new(None, shutdown_rx) - .storage_engine(storage) - .state_machine(state_machine) - .start() - .await?; - - // Run until shutdown - node.run().await?; + let engine = EmbeddedEngine::start_with("config.toml").await?; + engine.wait_ready(Duration::from_secs(5)).await?; + + let client = engine.client(); + client.put(b"key".to_vec(), b"value".to_vec()).await?; + + engine.stop().await?; Ok(()) } ``` -### 2. Three-Node Cluster (Production) +### Standalone Mode (independent server) -**Node 1** (`cluster.yaml`): +```rust +use d_engine_server::StandaloneServer; +use tokio::sync::watch; -```yaml -cluster_id: "prod-cluster" -node_id: 1 -rpc_addr: "0.0.0.0:9081" -peers: - - id: 2 - addr: "node2:9082" - - id: 3 - addr: "node3:9083" +#[tokio::main] +async fn main() -> Result<(), Box> { + std::env::set_var("CONFIG_PATH", "config.toml"); + let (_shutdown_tx, shutdown_rx) = watch::channel(()); + StandaloneServer::run(shutdown_rx).await?; + Ok(()) +} ``` -**Start node**: +--- -```rust -let node = NodeBuilder::new(Some("cluster.yaml"), shutdown_rx) - .storage_engine(storage) - .state_machine(state_machine) - .start() - .await?; +## Features + +This crate provides: -node.run().await?; +- **gRPC Server** - Production-ready Raft RPC implementation +- **Storage Backends** - File-based and RocksDB storage +- **Cluster Orchestration** - Node lifecycle and membership management +- **Snapshot Coordination** - Automatic log compaction +- **Watch API** (optional) - Real-time state change notifications +- **EmbeddedEngine API** - High-level API for embedded mode + +--- + +## Architecture + +```text +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ d-engine-server β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ API Layer β”‚ β”‚ +β”‚ β”‚ - EmbeddedEngine β”‚ β”‚ +β”‚ β”‚ - StandaloneServer β”‚ β”‚ +β”‚ β”‚ - LocalKvClient β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Node (Raft orchestration) β”‚ β”‚ +β”‚ β”‚ - Leader election β”‚ β”‚ +β”‚ β”‚ - Log replication β”‚ β”‚ +β”‚ β”‚ - Membership changes β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ StorageEngine β”‚ β”‚ StateMachine β”‚ β”‚ +β”‚ β”‚ (Raft logs) β”‚ β”‚ (KV store) β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ gRPC Services β”‚ β”‚ +β”‚ β”‚ - Client RPC (read/write) β”‚ β”‚ +β”‚ β”‚ - Cluster RPC (membership) β”‚ β”‚ +β”‚ β”‚ - Internal RPC (replication) β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` -Repeat for nodes 2 and 3 with their respective configs. +--- ## Storage Backends ### File Storage (Default) -Simple file-based storage. Good for development and small deployments. +Simple file-based storage for development and small deployments. ```rust use d_engine_server::{FileStorageEngine, FileStateMachine}; -let storage = Arc::new(FileStorageEngine::new("/tmp/logs")?); -let sm = Arc::new(FileStateMachine::new("/tmp/sm").await?); +let storage = Arc::new(FileStorageEngine::new("./logs")?); +let sm = Arc::new(FileStateMachine::new("./sm").await?); ``` -**Characteristics**: - -- One file per log entry -- Simple snapshot files -- No external dependencies - ### RocksDB Storage (Production) -High-performance embedded database. Recommended for production. +High-performance embedded database for production use. ```toml [dependencies] @@ -155,90 +151,95 @@ d-engine-server = { version = "0.2", features = ["rocksdb"] } ```rust use d_engine_server::{RocksDBStorageEngine, RocksDBStateMachine}; -let storage = Arc::new(RocksDBStorageEngine::new("/data/logs")?); -let sm = Arc::new(RocksDBStateMachine::new("/data/sm").await?); +let storage = Arc::new(RocksDBStorageEngine::new("./data/logs")?); +let sm = Arc::new(RocksDBStateMachine::new("./data/sm").await?); ``` -**Characteristics**: - -- LSM-tree storage engine -- Efficient compaction -- Better write throughput +--- -## Custom Storage Backend +## Custom Storage -Implement `StorageEngine` and `StateMachine` traits: +Implement [`StateMachine`] and [`StorageEngine`] traits: ```rust -use d_engine_server::{StorageEngine, StateMachine, LogStore, MetaStore}; -use d_engine_core::{Entry, Result}; +use d_engine_server::{StateMachine, StorageEngine}; -struct MyStorageEngine { /* ... */ } +struct MyStateMachine; +impl StateMachine for MyStateMachine { + // Apply committed entries to your application state +} +struct MyStorageEngine; impl StorageEngine for MyStorageEngine { - type LogStore = MyLogStore; - type MetaStore = MyMetaStore; - - fn log_store(&self) -> Arc { /* ... */ } - fn meta_store(&self) -> Arc { /* ... */ } + // Persist Raft logs and metadata } +``` -#[async_trait] -impl StateMachine for MyStateMachine { - async fn apply(&mut self, entry: Entry) -> Result> { - // Apply committed log entry - } +See the [Server Guide](https://docs.rs/d-engine/latest/d_engine/docs/server_guide/index.html) for detailed implementation instructions. - async fn snapshot(&self) -> Result> { - // Generate snapshot - } +--- - async fn restore(&mut self, snapshot: &[u8]) -> Result<()> { - // Restore from snapshot - } -} -``` +## EmbeddedEngine API + +High-level API for embedding d-engine in Rust applications: + +```rust +use d_engine_server::EmbeddedEngine; +use std::time::Duration; -## Client Integration +#[tokio::main] +async fn main() -> Result<(), Box> { + // Start embedded engine with config file + let engine = EmbeddedEngine::start_with("d-engine.toml").await?; -d-engine-server exposes three gRPC services: + // Wait for leader election + let leader = engine.wait_ready(Duration::from_secs(5)).await?; + println!("Leader elected: {}", leader.leader_id); -### 1. RaftClientService (Client Operations) + // Get zero-overhead client + let client = engine.client(); + client.put(b"key".to_vec(), b"value".to_vec()).await?; -```protobuf -service RaftClientService { - rpc HandleClientWrite (ClientWriteRequest) returns (ClientResponse); - rpc HandleClientRead (ClientReadRequest) returns (ClientResponse); + // Graceful shutdown + engine.stop().await?; + Ok(()) } ``` -Use **d-engine-client** (Rust) or generate bindings for your language: +--- -```bash -# Generate Go client -protoc --go_out=. --go-grpc_out=. proto/client/*.proto -``` +## Documentation -### 2. RaftService (Internal - Peer Replication) +For comprehensive guides: -For cluster nodes to communicate (not for application use). +- [Customize Storage Engine](https://docs.rs/d-engine/latest/d_engine/docs/server_guide/customize_storage_engine/index.html) +- [Customize State Machine](https://docs.rs/d-engine/latest/d_engine/docs/server_guide/customize_state_machine/index.html) +- [Watch Feature Guide](https://docs.rs/d-engine/latest/d_engine/docs/server_guide/watch_feature/index.html) +- [Consistency Tuning](https://docs.rs/d-engine/latest/d_engine/docs/server_guide/consistency_tuning/index.html) -### 3. RaftClusterService (Membership Management) +--- -```protobuf -service RaftClusterService { - rpc AddNode (AddNodeRequest) returns (AddNodeResponse); - rpc RemoveNode (RemoveNodeRequest) returns (RemoveNodeResponse); -} -``` +## Examples + +See working examples in the repository: + +- [Single Node Expansion](https://github.com/deventlab/d-engine/tree/main/examples/single-node-expansion) +- [Three Nodes Cluster](https://github.com/deventlab/d-engine/tree/main/examples/three-nodes-cluster) +- [Quick Start Embedded](https://github.com/deventlab/d-engine/tree/main/examples/quick-start-embedded) + +--- + +## Related Crates -## Resources +| Crate | Purpose | +| ------------------------------------------------------------- | ------------------------------------------------- | +| [`d-engine`](https://crates.io/crates/d-engine) | **Recommended** - Unified API for most users | +| [`d-engine-client`](https://crates.io/crates/d-engine-client) | Client library for Rust applications | +| [`d-engine-core`](https://crates.io/crates/d-engine-core) | Pure Raft algorithm for custom integrations | +| [`d-engine-proto`](https://crates.io/crates/d-engine-proto) | Protocol definitions (foundation for all clients) | -- **d-engine-client**: Rust client library -- **d-engine-proto**: Protocol buffer definitions -- **d-engine-core**: Core Raft implementation -- **d-engine-docs**: Architecture and design documentation +--- ## License -See LICENSE file in repository root. +MIT or Apache-2.0 diff --git a/d-engine-server/src/lib.rs b/d-engine-server/src/lib.rs index f27921c8..fe665458 100644 --- a/d-engine-server/src/lib.rs +++ b/d-engine-server/src/lib.rs @@ -1,52 +1,94 @@ //! # d-engine-server //! -//! Production-ready Raft consensus server implementation. +//! Complete Raft server with gRPC and storage - batteries included //! -//! ## Architecture -//! - [`node`] - Node lifecycle management -//! - [`storage`] - Pluggable storage backends -//! - Core Raft protocol (re-exported from `d-engine-core`) -//! - Protocol definitions (re-exported from `d-engine-proto`) +//! ## When to use this crate directly +//! +//! - βœ… Embedding server in a larger Rust application +//! - βœ… Need programmatic access to server APIs +//! - βœ… Building custom tooling around d-engine +//! - βœ… Already have your own client implementation +//! +//! ## When to use `d-engine` instead +//! +//! Most users should use [`d-engine`](https://crates.io/crates/d-engine): +//! +//! ```toml +//! [dependencies] +//! d-engine = { version = "0.2", features = ["server"] } +//! ``` +//! +//! It re-exports this crate plus optional client libraries with simpler dependency management. //! //! ## Quick Start -//! ```ignore -//! use d_engine_server::{NodeBuilder, FileStorageEngine, FileStateMachine}; -//! use std::sync::Arc; -//! use std::path::PathBuf; //! -//! #[tokio::main(flavor = "current_thread")] +//! **Embedded Mode** (zero-overhead local client): +//! +//! ```rust,ignore +//! use d_engine_server::EmbeddedEngine; +//! use std::time::Duration; +//! +//! #[tokio::main] //! async fn main() -> Result<(), Box> { -//! let (tx, rx) = tokio::sync::watch::channel(()); +//! let engine = EmbeddedEngine::start_with("config.toml").await?; +//! engine.wait_ready(Duration::from_secs(5)).await?; //! -//! let storage = Arc::new(FileStorageEngine::new(PathBuf::from("/tmp/storage"))?); -//! let state_machine = Arc::new(FileStateMachine::new(PathBuf::from("/tmp/sm")).await?); +//! let client = engine.client(); +//! client.put(b"key".to_vec(), b"value".to_vec()).await?; //! -//! let node = NodeBuilder::new(None, rx) -//! .storage_engine(storage) -//! .state_machine(state_machine) -//! .start() -//! .await?; +//! engine.stop().await?; +//! Ok(()) +//! } +//! ``` +//! +//! **Standalone Mode** (independent server): //! -//! node.run().await?; +//! ```rust,ignore +//! use d_engine_server::StandaloneServer; +//! use tokio::sync::watch; +//! +//! #[tokio::main] +//! async fn main() -> Result<(), Box> { +//! std::env::set_var("CONFIG_PATH", "config.toml"); +//! let (_shutdown_tx, shutdown_rx) = watch::channel(()); +//! StandaloneServer::run(shutdown_rx).await?; //! Ok(()) //! } //! ``` //! -//! ## Custom Storage Backend +//! ## Features +//! +//! This crate provides: +//! - **gRPC Server** - Production-ready Raft RPC implementation +//! - **Storage Backends** - File-based and RocksDB storage +//! - **Cluster Orchestration** - Node lifecycle and membership management +//! - **Snapshot Coordination** - Automatic log compaction +//! - **Watch API** - Real-time state change notifications +//! +//! ## Custom Storage //! //! Implement the [`StateMachine`] and [`StorageEngine`] traits: //! //! ```rust,ignore //! use d_engine_server::{StateMachine, StorageEngine}; //! -//! struct MyStateMachine { /* ... */ } -//! impl StateMachine for MyStateMachine { /* ... */ } +//! struct MyStateMachine; +//! impl StateMachine for MyStateMachine { +//! // Apply committed entries to your application state +//! } //! -//! struct MyStorageEngine { /* ... */ } -//! impl StorageEngine for MyStorageEngine { /* ... */ } +//! struct MyStorageEngine; +//! impl StorageEngine for MyStorageEngine { +//! // Persist Raft logs and metadata +//! } //! ``` //! -//! See the [d-engine-docs](https://docs.rs/d-engine-docs) for architecture details. +//! ## Documentation +//! +//! For comprehensive guides: +//! - [Customize Storage Engine](https://docs.rs/d-engine/latest/d_engine/docs/server_guide/customize_storage_engine/index.html) +//! - [Customize State Machine](https://docs.rs/d-engine/latest/d_engine/docs/server_guide/customize_state_machine/index.html) +//! - [Watch Feature Guide](https://docs.rs/d-engine/latest/d_engine/docs/server_guide/watch_feature/index.html) #![warn(missing_docs)] diff --git a/d-engine-server/src/membership/raft_membership.rs b/d-engine-server/src/membership/raft_membership.rs index fb966dc7..ac6b8da4 100644 --- a/d-engine-server/src/membership/raft_membership.rs +++ b/d-engine-server/src/membership/raft_membership.rs @@ -566,7 +566,8 @@ where .buffer_unordered(10) .for_each(|result| async move { if result.is_err() { - warn!("Connection pre-warming failed for one or more peers"); + // Use debug level - pre-warming failures during startup are expected + debug!("Connection pre-warming failed for one or more peers"); } }) .await; @@ -598,7 +599,8 @@ where // Remove failed connection from cache self.connection_cache.remove_node(node_id); self.health_monitor.record_failure(node_id).await; - warn!("Connection to node {} failed: {}", node_id, e); + // Use debug level - connection failures during startup are expected + debug!("Connection to node {} failed: {}", node_id, e); None } } diff --git a/d-engine-server/src/network/health_checker.rs b/d-engine-server/src/network/health_checker.rs index 1bb10924..1ae3a62d 100644 --- a/d-engine-server/src/network/health_checker.rs +++ b/d-engine-server/src/network/health_checker.rs @@ -57,8 +57,9 @@ impl HealthChecker { .connect() .await .map_err(|err| { - error!("connect to {} failed: {}", address, err); - eprintln!("{err:?}"); + // Use debug level during startup - connection failures are expected + // when peers are still starting up + tracing::debug!("Failed to connect to {}: {}", address, err); NetworkError::ConnectError(err.to_string()) })?; diff --git a/d-engine/Cargo.toml b/d-engine/Cargo.toml index 6a2553ea..3600ea2f 100644 --- a/d-engine/Cargo.toml +++ b/d-engine/Cargo.toml @@ -3,7 +3,7 @@ name = "d-engine" version.workspace = true edition.workspace = true authors.workspace = true -description = "A lightweight distributed coordination engine for Rust applicationsβ€”the consensus layer for building reliable distributed systems." +description = "Lightweight Raft consensus engine - recommended entry point for most users" homepage.workspace = true repository.workspace = true license.workspace = true diff --git a/d-engine-docs/src/docs/client_guide/error-handling.md b/d-engine/src/docs/client_guide/error-handling.md similarity index 100% rename from d-engine-docs/src/docs/client_guide/error-handling.md rename to d-engine/src/docs/client_guide/error-handling.md diff --git a/d-engine-docs/src/docs/client_guide/mod.rs b/d-engine/src/docs/client_guide/mod.rs similarity index 100% rename from d-engine-docs/src/docs/client_guide/mod.rs rename to d-engine/src/docs/client_guide/mod.rs diff --git a/d-engine-docs/src/docs/client_guide/read-consistency.md b/d-engine/src/docs/client_guide/read-consistency.md similarity index 100% rename from d-engine-docs/src/docs/client_guide/read-consistency.md rename to d-engine/src/docs/client_guide/read-consistency.md diff --git a/d-engine-docs/src/docs/examples/mod.rs b/d-engine/src/docs/examples/mod.rs similarity index 100% rename from d-engine-docs/src/docs/examples/mod.rs rename to d-engine/src/docs/examples/mod.rs diff --git a/d-engine-docs/src/docs/examples/single-node-expansion.md b/d-engine/src/docs/examples/single-node-expansion.md similarity index 100% rename from d-engine-docs/src/docs/examples/single-node-expansion.md rename to d-engine/src/docs/examples/single-node-expansion.md diff --git a/d-engine-docs/src/docs/examples/three-nodes-cluster.md b/d-engine/src/docs/examples/three-nodes-cluster.md similarity index 100% rename from d-engine-docs/src/docs/examples/three-nodes-cluster.md rename to d-engine/src/docs/examples/three-nodes-cluster.md diff --git a/d-engine-docs/src/docs/integration-modes.md b/d-engine/src/docs/integration-modes.md similarity index 100% rename from d-engine-docs/src/docs/integration-modes.md rename to d-engine/src/docs/integration-modes.md diff --git a/d-engine-docs/src/docs/mod.rs b/d-engine/src/docs/mod.rs similarity index 70% rename from d-engine-docs/src/docs/mod.rs rename to d-engine/src/docs/mod.rs index 733d3bc0..24817f54 100644 --- a/d-engine-docs/src/docs/mod.rs +++ b/d-engine/src/docs/mod.rs @@ -5,9 +5,9 @@ //! //! ## Documentation Sections //! -//! - [Client Guide](self::client_guide) - Client application development and API usage -//! - [Performance](self::performance) - Optimization techniques and benchmarking -//! - [Server Guide](self::server_guide) - Server deployment and customization +//! - [Client Guide](crate::docs::client_guide) - Client application development and API usage +//! - [Performance](crate::docs::performance) - Optimization techniques and benchmarking +//! - [Server Guide](crate::docs::server_guide) - Server deployment and customization pub mod quick_start_5min { #![doc = include_str!("quick-start-5min.md")] diff --git a/d-engine/src/docs/overview.md b/d-engine/src/docs/overview.md new file mode 100644 index 00000000..b7389360 --- /dev/null +++ b/d-engine/src/docs/overview.md @@ -0,0 +1,94 @@ +# d-engine - Distributed Coordination Engine + +**d-engine** is a lightweight distributed coordination engine written in Rust, designed for +embedding into applications that need strong consistencyβ€”the consensus layer for building +reliable distributed systems. + +## πŸš€ New to d-engine? Start Here + +Follow this learning path to get started quickly: + +```text +1. Is d-engine Right for You? (1 minute) + ↓ +2. Choose Integration Mode (1 minute) + ↓ +3a. Quick Start - Embedded (5 minutes) + OR +3b. Quick Start - Standalone (5 minutes) + ↓ +4. Scale to Cluster (optional) +``` + +**β†’ Start: [Is d-engine Right for You?](crate::docs::use_cases)** + +## Crate Organization + +| Crate | Purpose | +| ------------------- | ------------------------------- | +| **d-engine-proto** | Protocol definitions (Prost) | +| **d-engine-core** | Core Raft algorithm & traits | +| **d-engine-client** | Client library for applications | +| **d-engine-server** | Server runtime implementation | + +## Quick Start + +### Embedded Mode (Rust) + +```rust,ignore +use d_engine::prelude::*; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let engine = EmbeddedEngine::with_rocksdb("./data", None).await?; + engine.wait_ready(std::time::Duration::from_secs(5)).await?; + + let client = engine.client(); + client.put(b"key".to_vec(), b"value".to_vec()).await?; + + Ok(()) +} +``` + +**β†’ [5-Minute Embedded Guide](crate::docs::quick_start_5min)** + +### Standalone Mode (Any Language) + +```bash +cd examples/three-nodes-cluster +make start-cluster +``` + +**β†’ [Standalone Guide](crate::docs::quick_start_standalone)** + +## Documentation Index + +### Getting Started + +- [Is d-engine Right for You?](crate::docs::use_cases) - Common use cases +- [Integration Modes](crate::docs::integration_modes) - Embedded vs Standalone +- [Quick Start - Embedded](crate::docs::quick_start_5min) +- [Quick Start - Standalone](crate::docs::quick_start_standalone) + +### Guides by Role + +#### Client Developers + +- [Read Consistency](crate::docs::client_guide::read_consistency) - Choosing consistency policies +- [Error Handling](crate::docs::client_guide::error_handling) + +#### Server Operators + +- [Customize Storage Engine](crate::docs::server_guide::customize_storage_engine) +- [Customize State Machine](crate::docs::server_guide::customize_state_machine) +- [Consistency Tuning](crate::docs::server_guide::consistency_tuning) +- [Watch Feature](crate::docs::server_guide::watch_feature) + +### Examples & Performance + +- [Single Node Expansion](crate::docs::examples::single_node_expansion) - Scale from 1 to 3 nodes +- [Throughput Optimization](crate::docs::performance::throughput_optimization_guide) + +## License + +MIT or Apache-2.0 diff --git a/d-engine-docs/src/docs/performance/mod.rs b/d-engine/src/docs/performance/mod.rs similarity index 100% rename from d-engine-docs/src/docs/performance/mod.rs rename to d-engine/src/docs/performance/mod.rs diff --git a/d-engine-docs/src/docs/performance/throughput-optimization-guide.md b/d-engine/src/docs/performance/throughput-optimization-guide.md similarity index 100% rename from d-engine-docs/src/docs/performance/throughput-optimization-guide.md rename to d-engine/src/docs/performance/throughput-optimization-guide.md diff --git a/d-engine-docs/src/docs/quick-start-5min.md b/d-engine/src/docs/quick-start-5min.md similarity index 100% rename from d-engine-docs/src/docs/quick-start-5min.md rename to d-engine/src/docs/quick-start-5min.md diff --git a/d-engine-docs/src/docs/quick-start-standalone.md b/d-engine/src/docs/quick-start-standalone.md similarity index 100% rename from d-engine-docs/src/docs/quick-start-standalone.md rename to d-engine/src/docs/quick-start-standalone.md diff --git a/d-engine-docs/src/docs/server_guide/consistency-tuning.md b/d-engine/src/docs/server_guide/consistency-tuning.md similarity index 100% rename from d-engine-docs/src/docs/server_guide/consistency-tuning.md rename to d-engine/src/docs/server_guide/consistency-tuning.md diff --git a/d-engine-docs/src/docs/server_guide/customize-state-machine.md b/d-engine/src/docs/server_guide/customize-state-machine.md similarity index 98% rename from d-engine-docs/src/docs/server_guide/customize-state-machine.md rename to d-engine/src/docs/server_guide/customize-state-machine.md index 72c1e8c8..62470087 100644 --- a/d-engine-docs/src/docs/server_guide/customize-state-machine.md +++ b/d-engine/src/docs/server_guide/customize-state-machine.md @@ -206,7 +206,7 @@ NodeBuilder::new(config, shutdown_rx) See complete implementations in: -- `examples/rocksdb-cluster/src/main.rs` - RocksDB state machine +- `examples/three-nodes-cluster/src/main.rs` - Production cluster with RocksDB - `examples/sled-cluster/src/main.rs` - Sled state machine - `src/storage/adaptors/` - Built-in implementations diff --git a/d-engine-docs/src/docs/server_guide/customize-storage-engine.md b/d-engine/src/docs/server_guide/customize-storage-engine.md similarity index 100% rename from d-engine-docs/src/docs/server_guide/customize-storage-engine.md rename to d-engine/src/docs/server_guide/customize-storage-engine.md diff --git a/d-engine-docs/src/docs/server_guide/mod.rs b/d-engine/src/docs/server_guide/mod.rs similarity index 100% rename from d-engine-docs/src/docs/server_guide/mod.rs rename to d-engine/src/docs/server_guide/mod.rs diff --git a/d-engine-docs/src/docs/server_guide/watch-feature.md b/d-engine/src/docs/server_guide/watch-feature.md similarity index 100% rename from d-engine-docs/src/docs/server_guide/watch-feature.md rename to d-engine/src/docs/server_guide/watch-feature.md diff --git a/d-engine-docs/src/docs/use-cases.md b/d-engine/src/docs/use-cases.md similarity index 100% rename from d-engine-docs/src/docs/use-cases.md rename to d-engine/src/docs/use-cases.md diff --git a/d-engine/src/lib.rs b/d-engine/src/lib.rs index f161ea2f..2a35d95f 100644 --- a/d-engine/src/lib.rs +++ b/d-engine/src/lib.rs @@ -1,243 +1,32 @@ -//! # d-engine -//! -//! A lightweight and strongly consistent Raft consensus engine written in Rust. -//! Build reliable and scalable distributed systems by embedding d-engine into your applications. -//! -//! ## What's New in v0.2.0 -//! -//! - **Modular workspace**: Use `features = ["client"]` to reduce dependencies -//! - **TTL/Lease**: Automatic key expiration for distributed locks -//! - **Watch API**: Real-time key change notifications -//! - **EmbeddedEngine**: Single-node start, scale to 3 nodes with zero code changes -//! - **LocalKvClient**: Zero-overhead in-process access (<0.1ms latency) -//! -//! See the [CHANGELOG](https://github.com/deventlab/d-engine/blob/main/CHANGELOG.md) for full details. -//! -//! ## Quick Start -//! -//! Add d-engine to your `Cargo.toml` with features you need: -//! -//! ```toml -//! # For client-only applications -//! d-engine = { version = "0.2", features = ["client"] } -//! -//! # For server/embedded applications -//! d-engine = { version = "0.2", features = ["server"] } -//! -//! # For applications that need both -//! d-engine = { version = "0.2", features = ["full"] } -//! ``` -//! -//! ## Features -//! -//! - **`client`** - Client library for connecting to d-engine servers -//! - **`server`** - Embed a d-engine Raft server into your application -//! - **`full`** - Both client and server capabilities -//! -//! ## Client Example -//! -//! ```rust,ignore -//! use d_engine::Client; -//! -//! #[tokio::main] -//! async fn main() -> Result<(), Box> { -//! let client = Client::builder(vec![ -//! "http://localhost:9081".into(), -//! "http://localhost:9082".into(), -//! ]) -//! .build() -//! .await?; -//! -//! // Write data -//! client.kv().put("key", "value").await?; -//! -//! // Read data -//! let value = client.kv().get("key").await?; -//! println!("Value: {:?}", value); -//! -//! Ok(()) -//! } -//! ``` -//! -//! ## Server Example (Embedded) -//! -//! ```rust,ignore -//! use d_engine::{NodeBuilder, FileStorageEngine, FileStateMachine}; -//! use std::sync::Arc; -//! use std::path::PathBuf; -//! -//! #[tokio::main] -//! async fn main() -> Result<(), Box> { -//! let (tx, rx) = tokio::sync::watch::channel(()); -//! -//! let storage = Arc::new(FileStorageEngine::new(PathBuf::from("/tmp/storage"))?); -//! let state_machine = Arc::new(FileStateMachine::new(PathBuf::from("/tmp/sm")).await?); -//! -//! let node = NodeBuilder::new(None, rx) -//! .storage_engine(storage) -//! .state_machine(state_machine) -//! .start_server() -//! .await?; -//! -//! node.run().await?; -//! Ok(()) -//! } -//! ``` -//! -//! ## Architecture -//! -//! d-engine is designed with a modular architecture: -//! -//! - **d-engine-proto**: Protocol definitions (Protobuf/gRPC) -//! - **d-engine-core**: Core Raft algorithm implementation -//! - **d-engine-client**: Client library for cluster communication -//! - **d-engine-server**: Production-ready server runtime -//! -//! This main crate re-exports the public APIs from these components based on -//! enabled features, providing a unified interface for developers. - #![warn(missing_docs)] -#![cfg_attr(docsrs, feature(doc_cfg))] - -// ==================== Client API ==================== - -#[cfg(feature = "client")] -#[cfg_attr(docsrs, doc(cfg(feature = "client")))] -pub use d_engine_client::{ - // Main entry points - Client, - // Error types - ClientApiError, - ClientBuilder, - // Configuration - ClientConfig, - // Specialized clients - ClusterClient, - GrpcKvClient, -}; - -#[cfg(feature = "client")] -#[cfg_attr(docsrs, doc(cfg(feature = "client")))] -/// Protocol types for client operations -pub mod protocol { - pub use d_engine_client::protocol::ClientResult; - pub use d_engine_client::protocol::ReadConsistencyPolicy; - pub use d_engine_client::protocol::WriteCommand; -} - -#[cfg(feature = "client")] -#[cfg_attr(docsrs, doc(cfg(feature = "client")))] -/// Cluster management types -pub mod cluster_types { - pub use d_engine_client::cluster_types::NodeMeta; - pub use d_engine_client::cluster_types::NodeStatus; -} - -// ==================== Core API ==================== - -#[cfg(feature = "client")] -#[cfg_attr(docsrs, doc(cfg(feature = "client")))] -pub use d_engine_client::KvClient; -#[cfg(all(feature = "server", feature = "rocksdb"))] -#[cfg_attr(docsrs, doc(cfg(all(feature = "server", feature = "rocksdb"))))] -pub use d_engine_server::RocksDBStateMachine; -#[cfg(all(feature = "server", feature = "rocksdb"))] -#[cfg_attr(docsrs, doc(cfg(all(feature = "server", feature = "rocksdb"))))] -pub use d_engine_server::RocksDBStorageEngine; -// ==================== Server API ==================== -#[cfg(feature = "server")] -#[cfg_attr(docsrs, doc(cfg(feature = "server")))] -pub use d_engine_server::{ - // Embedded mode - EmbeddedEngine, - // Error types - Error, - // Storage implementations - FileStateMachine, - FileStorageEngine, - // Data types - HardState, - LeaderInfo, - // Embedded KV client (zero-overhead, same process) - LocalKvClient, - // Extension traits for custom implementations - LogStore, - MetaStore, - // Main entry points - Node, - NodeBuilder, - ProstError, - Result, - SnapshotError, - // Standalone mode - StandaloneServer, - StateMachine, - StorageEngine, - StorageError, -}; - -#[cfg(feature = "server")] -#[cfg_attr(docsrs, doc(cfg(feature = "server")))] -/// Common Raft protocol types -pub mod common { - pub use d_engine_server::common::Entry; - pub use d_engine_server::common::EntryPayload; - pub use d_engine_server::common::LogId; - pub use d_engine_server::common::entry_payload; -} - -#[cfg(feature = "server")] -#[cfg_attr(docsrs, doc(cfg(feature = "server")))] -/// Client write command types -pub mod write_command { - pub use d_engine_server::client::WriteCommand; - pub use d_engine_server::client::write_command; -} +#![doc = include_str!("docs/overview.md")] +// Re-export server components when server feature is enabled #[cfg(feature = "server")] -#[cfg_attr(docsrs, doc(cfg(feature = "server")))] -/// Server storage types -pub mod storage { - pub use d_engine_server::server_storage::SnapshotMetadata; -} +pub use d_engine_server::*; -// ==================== Convenience Re-exports ==================== +// Re-export client components when client feature is enabled +#[cfg(feature = "client")] +pub use d_engine_client::*; -/// Convenient prelude for quick imports +/// Convenient prelude for importing common types /// -/// Import everything you need with: /// ```rust,ignore /// use d_engine::prelude::*; /// ``` pub mod prelude { - #[cfg(feature = "client")] - pub use d_engine_client::Client; - #[cfg(feature = "client")] - pub use d_engine_client::ClientBuilder; - #[cfg(feature = "client")] - pub use d_engine_client::GrpcKvClient; - #[cfg(feature = "client")] - pub use d_engine_client::KvClient; - #[cfg(feature = "server")] - pub use d_engine_server::EmbeddedEngine; - #[cfg(feature = "server")] - pub use d_engine_server::FileStateMachine; - #[cfg(feature = "server")] - pub use d_engine_server::FileStorageEngine; - #[cfg(feature = "server")] - pub use d_engine_server::LeaderInfo; #[cfg(feature = "server")] - pub use d_engine_server::LocalClientError; - #[cfg(feature = "server")] - pub use d_engine_server::LocalKvClient; - #[cfg(feature = "server")] - pub use d_engine_server::Node; - #[cfg(feature = "server")] - pub use d_engine_server::NodeBuilder; - #[cfg(feature = "server")] - pub use d_engine_server::StandaloneServer; - #[cfg(feature = "server")] - pub use d_engine_server::StateMachine; - #[cfg(feature = "server")] - pub use d_engine_server::StorageEngine; + pub use d_engine_server::{ + EmbeddedEngine, Error, FileStateMachine, FileStorageEngine, LocalKvClient, Node, + NodeBuilder, Result, StandaloneServer, StateMachine, StorageEngine, + }; + + #[cfg(feature = "rocksdb")] + pub use d_engine_server::{RocksDBStateMachine, RocksDBStorageEngine}; + + #[cfg(feature = "client")] + pub use d_engine_client::{Client, ClientBuilder, KvClient}; } + +/// Documentation modules +pub mod docs; diff --git a/examples/README.md b/examples/README.md index 9d32bba6..945cd794 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,18 +1,81 @@ -# D-Engine Examples +# d-engine Examples -This directory contains usage examples for D-Engine distributed system. +Usage examples demonstrating different d-engine integration modes. -## Available Examples +--- -### Client Usage -- Demonstrates basic client operations with DEngine -- Location: `client_usage/` +## Quick Start Examples -### Three-Node Cluster -- Shows how to bootstrap a 3-node DEngine cluster -- Location: `three-nodes-cluster/` +**New to d-engine? Start here:** + +| Example | Mode | Time | Description | +| ------------------------------------------------- | ---------- | ----- | ------------------------------------------------------- | +| [quick-start-embedded](quick-start-embedded/) | Embedded | 5 min | Single-process Rust app with zero-overhead local client | +| [quick-start-standalone](quick-start-standalone/) | Standalone | 5 min | Go client connecting to 3-node d-engine cluster | + +--- + +## Integration Modes + +### Embedded Mode (Single Process) + +| Example | Description | +| --------------------------------------------------------- | ------------------------------------------ | +| [quick-start-embedded](quick-start-embedded/) | Basic embedded usage with local KV client | +| [service-discovery-embedded](service-discovery-embedded/) | Service discovery pattern in embedded mode | + +**Use case**: Maximum performance, zero network overhead, single-process applications + +--- + +### Standalone Mode (Client-Server) + +| Example | Description | +| ------------------------------------------------------------- | --------------------------------------------- | +| [quick-start-standalone](quick-start-standalone/) | Go client + 3-node cluster | +| [service-discovery-standalone](service-discovery-standalone/) | Service discovery with separate client/server | +| [client_usage](client_usage/) | Rust gRPC client examples | + +**Use case**: Language flexibility, separate services, microservices architecture + +--- + +## Cluster Management + +| Example | Description | +| ----------------------------------------------- | ------------------------------------- | +| [three-nodes-cluster](three-nodes-cluster/) | Bootstrap 3-node cluster from scratch | +| [single-node-expansion](single-node-expansion/) | Start with 1 node, expand to 3 nodes | + +--- + +## Storage Backend Examples + +| Example | Description | +| ----------------------------- | --------------------------------------- | +| [sled-cluster](sled-cluster/) | Alternative with Sled embedded database | + +--- ## Requirements -- Rust 1.7+ -- Protobuf compiler -- Linux/MacOS (Windows WSL2 supported) \ No newline at end of file + +- **Rust**: 1.85+ +- **Go**: 1.20+ (for Go examples) +- **Protobuf**: libprotoc 3.0+ (for code generation) +- **OS**: Linux/macOS + +--- + +## Running Examples + +```bash +# Rust examples +cd examples/quick-start-embedded +cargo run + +# Go examples +cd examples/quick-start-standalone +make run +``` + +See individual example READMEs for detailed instructions. diff --git a/examples/client_usage/README.md b/examples/client_usage/README.md index 4f777711..7da30c47 100644 --- a/examples/client_usage/README.md +++ b/examples/client_usage/README.md @@ -27,8 +27,5 @@ cargo run -- --endpoints "http://127.0.0.1:9083,http://127.0.0.1:9082,http://127 # Delete key cargo run -- --endpoints "http://127.0.0.1:9083,http://127.0.0.1:9082,http://127.0.0.1:9081" delete 42 -# Join cluster -cargo run -- --endpoints "http://127.0.0.1:9083,http://127.0.0.1:9082,http://127.0.0.1:9081" join \ - --node-id 100 \ - --address 127.0.0.1:9084 + ``` diff --git a/examples/quick-start-embedded/Makefile b/examples/quick-start-embedded/Makefile index 88e35b8c..fa0604d9 100644 --- a/examples/quick-start-embedded/Makefile +++ b/examples/quick-start-embedded/Makefile @@ -22,7 +22,7 @@ build: run: build @mkdir -p data/single-node - @./target/release/quick-start + @CONFIG_PATH=./d-engine.toml ./target/release/quick-start clean: rm -rf target/ data/ *.log diff --git a/examples/quick-start-embedded/README.md b/examples/quick-start-embedded/README.md index eece8d97..3421c0c2 100644 --- a/examples/quick-start-embedded/README.md +++ b/examples/quick-start-embedded/README.md @@ -18,13 +18,13 @@ Minimal example of embedding d-engine in a Rust application. ```bash # Clone and build -cd examples/quick-start +cd examples/quick-start-embedded make run ``` That's it! The engine starts with: -- Data stored in `./data/single-node` +- Data stored in `./data/single-node` (configured in `d-engine.toml`) - Single-node mode (no cluster) - Default port 9081 @@ -49,12 +49,14 @@ RUST_LOG=d_engine=trace make run You'll see: ``` -Starting d-engine in embedded mode... -Node 1 initialized -Node ready for operations -=== d-engine Embedded Mode Demo === -All operations: local-first, <0.1ms latency - +πŸš€ Starting d-engine... +βœ… d-engine ready! + β†’ Data directory: ./data/single-node + β†’ Node ID: 1 + β†’ Listening on: 127.0.0.1:9081 + +───────────────────────────────────── +=== Quick Start Demo === 1. Store workflow state βœ“ workflow:status = running 2. Read workflow state @@ -70,39 +72,33 @@ All operations: local-first, <0.1ms latency === Demo Complete === All data persisted locally and durable -Press Ctrl+C to exit +Scale to cluster: https://docs.rs/d-engine/latest/d_engine/docs/examples/single_node_expansion/index.html + +───────────────────────────────────── +πŸ›‘ Shutting down... +βœ… Stopped cleanly ``` ## How It Works -The example demonstrates 5 key steps: +The example demonstrates 3 simple steps: ```rust -// 1. Create storage engine (persists Raft logs) -let storage = Arc::new(RocksDBStorageEngine::new(path)?); - -// 2. Create state machine (persists KV data) -let state_machine = Arc::new(RocksDBStateMachine::new(path)?); - -// 3. Create shutdown signal -let (shutdown_tx, shutdown_rx) = watch::channel(()); +// 1. Start embedded engine with config file +let engine = EmbeddedEngine::start_with("d-engine.toml").await?; -// 4. Build the Raft node -let node = NodeBuilder::new(None, shutdown_rx) - .storage_engine(storage) - .state_machine(state_machine) - .start() - .await?; +// 2. Wait for leader election (single-node: instant) +let leader = engine.wait_ready(Duration::from_secs(5)).await?; -// 5. Get the embedded KV client (in-process, zero-copy) -let client = node.local_client(); +// 3. Get the embedded KV client (in-process, zero-copy) +let client = engine.client(); ``` Then use it like a local HashMap: ```rust -client.put("key", b"value").await?; -let value = client.get("key").await?; +client.put("key".as_bytes().to_vec(), b"value".to_vec()).await?; +let value = client.get_eventual("key".as_bytes().to_vec()).await?; ``` All operations run locally in your process. No network calls. No serialization overhead. @@ -122,14 +118,14 @@ This example runs a single-node d-engine. The node automatically becomes leader When you need high availability, add peers to your configuration. Your application code stays unchanged. -See [Single-Node Expansion](../../../d-engine-docs/src/docs/examples/single-node-expansion.md) for step-by-step instructions. +See [Single-Node Expansion](https://docs.rs/d-engine/latest/d_engine/docs/examples/single_node_expansion/index.html) for step-by-step instructions. ## Using This as a Template Copy this example and modify `src/main.rs`: -1. Replace `demo_kv_operations()` with your own business logic -2. Use `client.put()` and `client.get()` for distributed state +1. Replace `run_demo()` with your own business logic +2. Use `client.put()` and `client.get_eventual()` for distributed state 3. Keep everything else as-is Example: @@ -137,8 +133,8 @@ Example: ```rust async fn my_app(client: &LocalKvClient) -> Result<(), Box> { // Your code here - client.put("user:1:name", b"alice").await?; - client.put("user:1:email", b"alice@example.com").await?; + client.put("user:1:name".as_bytes().to_vec(), b"alice".to_vec()).await?; + client.put("user:1:email".as_bytes().to_vec(), b"alice@example.com".to_vec()).await?; Ok(()) } ``` @@ -174,8 +170,8 @@ make run ## Next Steps -- Read the full [quick-start guide](../../../d-engine-docs/src/docs/quick-start-5min.md) -- Learn about [scaling to clusters](../../../d-engine-docs/src/docs/examples/single-node-expansion.md) +- Read the full [quick-start guide](https://docs.rs/d-engine/latest/d_engine/docs/quick_start_5min/index.html) +- Learn about [scaling to clusters](https://docs.rs/d-engine/latest/d_engine/docs/examples/single_node_expansion/index.html) - Explore more [examples](../) ## Key Takeaways diff --git a/examples/quick-start-embedded/src/main.rs b/examples/quick-start-embedded/src/main.rs index f43cd31f..38d41be7 100644 --- a/examples/quick-start-embedded/src/main.rs +++ b/examples/quick-start-embedded/src/main.rs @@ -4,11 +4,11 @@ //! All KV operations run locally with <0.1ms latency. use d_engine::prelude::*; -use std::error::Error; +use std::error::Error as StdError; use std::time::Duration; #[tokio::main] -async fn main() -> Result<(), Box> { +async fn main() -> std::result::Result<(), Box> { // Optional: control d-engine logs via RUST_LOG env (default: warn) tracing_subscriber::fmt() .with_env_filter( @@ -46,17 +46,23 @@ async fn main() -> Result<(), Box> { Ok(()) } -async fn run_demo(client: &LocalKvClient) -> Result<(), Box> { +async fn run_demo(client: &LocalKvClient) -> std::result::Result<(), Box> { println!("=== Quick Start Demo ==="); // Store workflow state println!("1. Store workflow state"); - client.put("workflow:status".as_bytes().to_vec(), b"running".to_vec()).await?; + client + .put("workflow:status".as_bytes().to_vec(), b"running".to_vec()) + .await + .map_err(|e| Box::new(e) as Box)?; println!(" βœ“ workflow:status = running"); // Read it back println!("2. Read workflow state"); - let value = client.get_eventual("workflow:status".as_bytes().to_vec()).await?; + let value = client + .get_eventual("workflow:status".as_bytes().to_vec()) + .await + .map_err(|e| Box::new(e) as Box)?; if let Some(v) = value { println!(" βœ“ workflow:status = {}", String::from_utf8_lossy(&v)); } @@ -65,7 +71,10 @@ async fn run_demo(client: &LocalKvClient) -> Result<(), Box> { println!("3. Store task results"); for i in 1..=3 { let key = format!("task:{i}"); - client.put(key.as_bytes().to_vec(), b"completed".to_vec()).await?; + client + .put(key.as_bytes().to_vec(), b"completed".to_vec()) + .await + .map_err(|e| Box::new(e) as Box)?; println!(" βœ“ {key} stored"); } @@ -73,7 +82,11 @@ async fn run_demo(client: &LocalKvClient) -> Result<(), Box> { println!("4. Retrieve task results"); for i in 1..=3 { let key = format!("task:{i}"); - if let Some(v) = client.get_eventual(key.as_bytes().to_vec()).await? { + if let Some(v) = client + .get_eventual(key.as_bytes().to_vec()) + .await + .map_err(|e| Box::new(e) as Box)? + { println!(" βœ“ {key} = {}", String::from_utf8_lossy(&v)); } } @@ -81,7 +94,7 @@ async fn run_demo(client: &LocalKvClient) -> Result<(), Box> { println!("\n=== Demo Complete ==="); println!("All data persisted locally and durable"); println!( - "Scale to cluster: https://docs.rs/d-engine-docs/latest/d_engine_docs/docs/examples/single_node_expansion.html\n" + "Scale to cluster: https://docs.rs/d-engine/latest/d_engine/docs/examples/single_node_expansion/index.html\n" ); Ok(()) diff --git a/examples/quick-start-standalone/README.md b/examples/quick-start-standalone/README.md index cffe18a9..8401f4a2 100644 --- a/examples/quick-start-standalone/README.md +++ b/examples/quick-start-standalone/README.md @@ -34,4 +34,4 @@ Value: world ## Full Documentation -See [Quick Start: Standalone Mode](../../d-engine-docs/src/docs/quick-start-standalone.md) +See [Quick Start: Standalone Mode](https://docs.rs/d-engine/latest/d_engine/docs/quick_start_standalone/index.html) diff --git a/examples/rocksdb-cluster/.gitignore b/examples/rocksdb-cluster/.gitignore deleted file mode 100644 index 20366bf6..00000000 --- a/examples/rocksdb-cluster/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -# Generated by Cargo -# will have compiled files and executables -debug/ -target/ - -# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries -# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html -Cargo.lock - -# These are backup files generated by rustfmt -**/*.rs.bk - -# MSVC Windows builds of rustc generate these, which store debugging information -*.pdb - -# RustRover -# JetBrains specific template is maintained in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ - -db -db/* -logs -logs/* -snapshots -snapshots/* -sample_reports/* - -.idea -.idea/* - - -cobertura.xml -.DS_Store diff --git a/examples/rocksdb-cluster/Cargo.lock b/examples/rocksdb-cluster/Cargo.lock deleted file mode 100644 index d96d9824..00000000 --- a/examples/rocksdb-cluster/Cargo.lock +++ /dev/null @@ -1,2795 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - -[[package]] -name = "ahash" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "aho-corasick" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" -dependencies = [ - "memchr", -] - -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - -[[package]] -name = "anyhow" -version = "1.0.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" - -[[package]] -name = "arc-swap" -version = "1.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" - -[[package]] -name = "astral-tokio-tar" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec179a06c1769b1e42e1e2cbe74c7dcdb3d6383c838454d063eaac5bbb7ebbe5" -dependencies = [ - "filetime", - "futures-core", - "libc", - "portable-atomic", - "rustc-hash", - "tokio", - "tokio-stream", - "xattr", -] - -[[package]] -name = "async-compression" -version = "0.4.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a89bce6054c720275ac2432fbba080a66a2106a44a1b804553930ca6909f4e0" -dependencies = [ - "compression-codecs", - "compression-core", - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "async-stream" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "async-trait" -version = "0.1.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "aws-lc-rs" -version = "1.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879b6c89592deb404ba4dc0ae6b58ffd1795c78991cbb5b8bc441c48a070440d" -dependencies = [ - "aws-lc-sys", - "zeroize", -] - -[[package]] -name = "aws-lc-sys" -version = "0.32.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "107a4e9d9cab9963e04e84bb8dee0e25f2a987f9a8bad5ed054abd439caa8f8c" -dependencies = [ - "bindgen", - "cc", - "cmake", - "dunce", - "fs_extra", -] - -[[package]] -name = "axum" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" -dependencies = [ - "async-trait", - "axum-core", - "bytes", - "futures-util", - "http", - "http-body", - "http-body-util", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "sync_wrapper", - "tower 0.5.2", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http", - "http-body", - "http-body-util", - "mime", - "pin-project-lite", - "rustversion", - "sync_wrapper", - "tower-layer", - "tower-service", -] - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bincode" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740" -dependencies = [ - "bincode_derive", - "serde", - "unty", -] - -[[package]] -name = "bincode_derive" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf95709a440f45e986983918d0e8a1f30a9b1df04918fc828670606804ac3c09" -dependencies = [ - "virtue", -] - -[[package]] -name = "bindgen" -version = "0.72.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" -dependencies = [ - "bitflags", - "cexpr", - "clang-sys", - "itertools 0.13.0", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn", -] - -[[package]] -name = "bitflags" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bumpalo" -version = "3.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" - -[[package]] -name = "bytes" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" -dependencies = [ - "serde", -] - -[[package]] -name = "bzip2-sys" -version = "0.1.13+1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" -dependencies = [ - "cc", - "pkg-config", -] - -[[package]] -name = "cc" -version = "1.2.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37521ac7aabe3d13122dc382493e20c9416f299d2ccd5b3a5340a2570cdeb0f3" -dependencies = [ - "find-msvc-tools", - "jobserver", - "libc", - "shlex", -] - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[package]] -name = "cfg-if" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" - -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - -[[package]] -name = "cmake" -version = "0.1.54" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" -dependencies = [ - "cc", -] - -[[package]] -name = "compression-codecs" -version = "0.4.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8a506ec4b81c460798f572caead636d57d3d7e940f998160f52bd254bf2d23" -dependencies = [ - "compression-core", - "flate2", - "memchr", -] - -[[package]] -name = "compression-core" -version = "0.4.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb" - -[[package]] -name = "config" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68578f196d2a33ff61b27fae256c3164f65e36382648e30666dde05b8cc9dfdf" -dependencies = [ - "nom", - "pathdiff", - "serde", - "toml", -] - -[[package]] -name = "core-foundation" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-epoch", - "crossbeam-queue", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-queue" -version = "0.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-skiplist" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df29de440c58ca2cc6e587ec3d22347551a32435fbde9d2bff64e78a9ffa151b" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "d-engine" -version = "0.2.0" -dependencies = [ - "d-engine-server", -] - -[[package]] -name = "d-engine-client" -version = "0.2.0" -dependencies = [ - "arc-swap", - "async-trait", - "bytes", - "d-engine-core", - "d-engine-proto", - "futures", - "rand 0.8.5", - "serde", - "tokio", - "tokio-stream", - "tonic", - "tonic-health", - "tracing", -] - -[[package]] -name = "d-engine-core" -version = "0.2.0" -dependencies = [ - "astral-tokio-tar", - "async-compression", - "async-stream", - "async-trait", - "bincode 1.3.3", - "bytes", - "config", - "crc32fast", - "crossbeam", - "crossbeam-channel", - "crossbeam-skiplist", - "d-engine-proto", - "dashmap", - "futures", - "http-body", - "http-body-util", - "lru", - "memmap2", - "metrics", - "nanoid", - "prost", - "rand 0.8.5", - "serde", - "sha2", - "tempfile", - "thiserror 1.0.69", - "tokio", - "tokio-stream", - "tonic", - "tracing", -] - -[[package]] -name = "d-engine-proto" -version = "0.2.0" -dependencies = [ - "bytes", - "prost", - "serde", - "tonic", - "tonic-build", - "tracing", - "vergen", -] - -[[package]] -name = "d-engine-server" -version = "0.2.0" -dependencies = [ - "arc-swap", - "async-trait", - "bincode 1.3.3", - "bytes", - "config", - "crc32fast", - "crossbeam", - "crossbeam-skiplist", - "d-engine-client", - "d-engine-core", - "d-engine-proto", - "dashmap", - "futures", - "http-body", - "http-body-util", - "metrics", - "parking_lot", - "prost", - "rcgen", - "rocksdb", - "serde", - "tempfile", - "tokio", - "tokio-stream", - "tokio-util", - "tonic", - "tonic-health", - "tracing", -] - -[[package]] -name = "dashmap" -version = "6.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" -dependencies = [ - "cfg-if", - "crossbeam-utils", - "hashbrown 0.14.5", - "lock_api", - "once_cell", - "parking_lot_core", -] - -[[package]] -name = "deranged" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" -dependencies = [ - "powerfmt", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer", - "crypto-common", -] - -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys 0.61.2", -] - -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "filetime" -version = "0.2.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" -dependencies = [ - "cfg-if", - "libc", - "libredox", - "windows-sys 0.60.2", -] - -[[package]] -name = "find-msvc-tools" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" - -[[package]] -name = "fixedbitset" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" - -[[package]] -name = "flate2" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - -[[package]] -name = "futures" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-executor" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-macro" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasip2", -] - -[[package]] -name = "glob" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" - -[[package]] -name = "h2" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http", - "indexmap 2.12.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" - -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "allocator-api2", - "equivalent", - "foldhash", -] - -[[package]] -name = "hashbrown" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "http" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" -dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "hyper" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" -dependencies = [ - "atomic-waker", - "bytes", - "futures-channel", - "futures-core", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "pin-utils", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" -dependencies = [ - "http", - "hyper", - "hyper-util", - "rustls", - "rustls-native-certs", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", -] - -[[package]] -name = "hyper-timeout" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" -dependencies = [ - "hyper", - "hyper-util", - "pin-project-lite", - "tokio", - "tower-service", -] - -[[package]] -name = "hyper-util" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http", - "http-body", - "hyper", - "libc", - "pin-project-lite", - "socket2 0.6.1", - "tokio", - "tower-service", - "tracing", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - -[[package]] -name = "indexmap" -version = "2.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" -dependencies = [ - "equivalent", - "hashbrown 0.16.0", -] - -[[package]] -name = "ipnet" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" - -[[package]] -name = "itertools" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" - -[[package]] -name = "jobserver" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" -dependencies = [ - "getrandom 0.3.4", - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "libc" -version = "0.2.177" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" - -[[package]] -name = "libloading" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" -dependencies = [ - "cfg-if", - "windows-link", -] - -[[package]] -name = "libredox" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" -dependencies = [ - "bitflags", - "libc", - "redox_syscall", -] - -[[package]] -name = "librocksdb-sys" -version = "0.17.3+10.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cef2a00ee60fe526157c9023edab23943fae1ce2ab6f4abb2a807c1746835de9" -dependencies = [ - "bindgen", - "bzip2-sys", - "cc", - "libc", - "libz-sys", - "lz4-sys", - "zstd-sys", -] - -[[package]] -name = "libz-sys" -version = "1.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "linux-raw-sys" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" - -[[package]] -name = "lock_api" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" -dependencies = [ - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" - -[[package]] -name = "lru" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0281c2e25e62316a5c9d98f2d2e9e95a37841afdaf4383c177dbb5c1dfab0568" -dependencies = [ - "hashbrown 0.15.5", -] - -[[package]] -name = "lz4-sys" -version = "1.11.1+lz4-1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bd8c0d6c6ed0cd30b3652886bb8711dc4bb01d637a68105a3d5158039b418e6" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "matchers" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" -dependencies = [ - "regex-automata", -] - -[[package]] -name = "matchit" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" - -[[package]] -name = "memchr" -version = "2.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" - -[[package]] -name = "memmap2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" -dependencies = [ - "libc", -] - -[[package]] -name = "metrics" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dea7ac8057892855ec285c440160265225438c3c45072613c25a4b26e98ef5" -dependencies = [ - "ahash", - "portable-atomic", -] - -[[package]] -name = "metrics-exporter-prometheus" -version = "0.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b166dea96003ee2531cf14833efedced545751d800f03535801d833313f8c15" -dependencies = [ - "base64", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-util", - "indexmap 2.12.0", - "ipnet", - "metrics", - "metrics-util", - "quanta", - "thiserror 2.0.17", - "tokio", - "tracing", -] - -[[package]] -name = "metrics-util" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe8db7a05415d0f919ffb905afa37784f71901c9a773188876984b4f769ab986" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", - "hashbrown 0.15.5", - "metrics", - "quanta", - "rand 0.9.2", - "rand_xoshiro", - "sketches-ddsketch", -] - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", - "simd-adler32", -] - -[[package]] -name = "mio" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.61.2", -] - -[[package]] -name = "multimap" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" - -[[package]] -name = "nanoid" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ffa00dec017b5b1a8b7cf5e2c008bfda1aa7e0697ac1508b491fdf2622fb4d8" -dependencies = [ - "rand 0.8.5", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - -[[package]] -name = "nu-ansi-term" -version = "0.50.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num_threads" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" -dependencies = [ - "libc", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "openssl-probe" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" - -[[package]] -name = "parking_lot" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-link", -] - -[[package]] -name = "pathdiff" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" - -[[package]] -name = "pem" -version = "3.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" -dependencies = [ - "base64", - "serde_core", -] - -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "petgraph" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" -dependencies = [ - "fixedbitset", - "indexmap 2.12.0", -] - -[[package]] -name = "pin-project" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - -[[package]] -name = "portable-atomic" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] - -[[package]] -name = "proc-macro2" -version = "1.0.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prost" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-build" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" -dependencies = [ - "heck", - "itertools 0.14.0", - "log", - "multimap", - "once_cell", - "petgraph", - "prettyplease", - "prost", - "prost-types", - "regex", - "syn", - "tempfile", -] - -[[package]] -name = "prost-derive" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d" -dependencies = [ - "anyhow", - "itertools 0.14.0", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "prost-types" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16" -dependencies = [ - "prost", -] - -[[package]] -name = "quanta" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3ab5a9d756f0d97bdc89019bd2e4ea098cf9cde50ee7564dde6b81ccc8f06c7" -dependencies = [ - "crossbeam-utils", - "libc", - "once_cell", - "raw-cpuid", - "wasi", - "web-sys", - "winapi", -] - -[[package]] -name = "quote" -version = "1.0.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" -dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.16", -] - -[[package]] -name = "rand_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" -dependencies = [ - "getrandom 0.3.4", -] - -[[package]] -name = "rand_xoshiro" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41" -dependencies = [ - "rand_core 0.9.3", -] - -[[package]] -name = "raw-cpuid" -version = "11.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" -dependencies = [ - "bitflags", -] - -[[package]] -name = "rcgen" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2" -dependencies = [ - "pem", - "ring", - "rustls-pki-types", - "time", - "yasna", -] - -[[package]] -name = "redox_syscall" -version = "0.5.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" -dependencies = [ - "bitflags", -] - -[[package]] -name = "regex" -version = "1.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" - -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.16", - "libc", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "rocksdb" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddb7af00d2b17dbd07d82c0063e25411959748ff03e8d4f96134c2ff41fce34f" -dependencies = [ - "libc", - "librocksdb-sys", -] - -[[package]] -name = "rocksdb-demo" -version = "0.2.0" -dependencies = [ - "async-trait", - "bincode 2.0.1", - "bytes", - "d-engine", - "metrics-exporter-prometheus", - "prost", - "tokio", - "tracing", - "tracing-appender", - "tracing-subscriber", -] - -[[package]] -name = "rustc-hash" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" - -[[package]] -name = "rustix" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" -dependencies = [ - "bitflags", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.61.2", -] - -[[package]] -name = "rustls" -version = "0.23.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9586e9ee2b4f8fab52a0048ca7334d7024eef48e2cb9407e3497bb7cab7fa7" -dependencies = [ - "aws-lc-rs", - "log", - "once_cell", - "ring", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-native-certs" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9980d917ebb0c0536119ba501e90834767bffc3d60641457fd84a1f3fd337923" -dependencies = [ - "openssl-probe", - "rustls-pki-types", - "schannel", - "security-framework", -] - -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "rustls-pki-types" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a" -dependencies = [ - "zeroize", -] - -[[package]] -name = "rustls-webpki" -version = "0.103.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" -dependencies = [ - "aws-lc-rs", - "ring", - "rustls-pki-types", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - -[[package]] -name = "schannel" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" -dependencies = [ - "windows-sys 0.61.2", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "security-framework" -version = "3.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", - "serde_derive", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.145" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", - "serde_core", -] - -[[package]] -name = "serde_spanned" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" -dependencies = [ - "serde", -] - -[[package]] -name = "sha2" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] - -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" -dependencies = [ - "libc", -] - -[[package]] -name = "simd-adler32" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" - -[[package]] -name = "sketches-ddsketch" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e9a774a6c28142ac54bb25d25562e6bcf957493a184f15ad4eebccb23e410a" - -[[package]] -name = "slab" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "socket2" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "socket2" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" -dependencies = [ - "libc", - "windows-sys 0.60.2", -] - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "syn" -version = "2.0.108" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" - -[[package]] -name = "tempfile" -version = "3.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" -dependencies = [ - "fastrand", - "getrandom 0.3.4", - "once_cell", - "rustix", - "windows-sys 0.61.2", -] - -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - -[[package]] -name = "thiserror" -version = "2.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" -dependencies = [ - "thiserror-impl 2.0.17", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "thread_local" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "time" -version = "0.3.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" -dependencies = [ - "deranged", - "itoa", - "libc", - "num-conv", - "num_threads", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" - -[[package]] -name = "time-macros" -version = "0.2.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tokio" -version = "1.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" -dependencies = [ - "bytes", - "libc", - "mio", - "pin-project-lite", - "signal-hook-registry", - "socket2 0.6.1", - "tokio-macros", - "windows-sys 0.61.2", -] - -[[package]] -name = "tokio-macros" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.22.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" -dependencies = [ - "indexmap 2.12.0", - "serde", - "serde_spanned", - "toml_datetime", - "toml_write", - "winnow", -] - -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - -[[package]] -name = "tonic" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" -dependencies = [ - "async-stream", - "async-trait", - "axum", - "base64", - "bytes", - "flate2", - "h2", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-timeout", - "hyper-util", - "percent-encoding", - "pin-project", - "prost", - "rustls-pemfile", - "socket2 0.5.10", - "tokio", - "tokio-rustls", - "tokio-stream", - "tower 0.4.13", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tonic-build" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9557ce109ea773b399c9b9e5dca39294110b74f1f342cb347a80d1fce8c26a11" -dependencies = [ - "prettyplease", - "proc-macro2", - "prost-build", - "prost-types", - "quote", - "syn", -] - -[[package]] -name = "tonic-health" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1eaf34ddb812120f5c601162d5429933c9b527d901ab0e7f930d3147e33a09b2" -dependencies = [ - "async-stream", - "prost", - "tokio", - "tokio-stream", - "tonic", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "indexmap 1.9.3", - "pin-project", - "pin-project-lite", - "rand 0.8.5", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" -dependencies = [ - "futures-core", - "futures-util", - "pin-project-lite", - "sync_wrapper", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-appender" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" -dependencies = [ - "crossbeam-channel", - "thiserror 1.0.69", - "time", - "tracing-subscriber", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "tracing-core" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" -dependencies = [ - "once_cell", - "valuable", -] - -[[package]] -name = "tracing-log" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" -dependencies = [ - "log", - "once_cell", - "tracing-core", -] - -[[package]] -name = "tracing-serde" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" -dependencies = [ - "serde", - "tracing-core", -] - -[[package]] -name = "tracing-subscriber" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex-automata", - "serde", - "serde_json", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", - "tracing-serde", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "typenum" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" - -[[package]] -name = "unicode-ident" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "unty" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" - -[[package]] -name = "valuable" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "vergen" -version = "8.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2990d9ea5967266ea0ccf413a4aa5c42a93dbcfda9cb49a97de6931726b12566" -dependencies = [ - "anyhow", - "cfg-if", - "rustversion", - "time", -] - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "virtue" -version = "0.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "051eb1abcf10076295e815102942cc58f9d5e3b4560e46e53c21e8ff6f3af7b1" - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "wasip2" -version = "1.0.1+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.105" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.105" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.105" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" -dependencies = [ - "bumpalo", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.105" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "web-sys" -version = "0.3.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-link" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", -] - -[[package]] -name = "windows-sys" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - -[[package]] -name = "winnow" -version = "0.7.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" -dependencies = [ - "memchr", -] - -[[package]] -name = "wit-bindgen" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" - -[[package]] -name = "xattr" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" -dependencies = [ - "libc", - "rustix", -] - -[[package]] -name = "yasna" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" -dependencies = [ - "time", -] - -[[package]] -name = "zerocopy" -version = "0.8.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "zeroize" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" - -[[package]] -name = "zstd-sys" -version = "2.0.16+zstd.1.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748" -dependencies = [ - "cc", - "pkg-config", -] diff --git a/examples/rocksdb-cluster/Cargo.toml b/examples/rocksdb-cluster/Cargo.toml deleted file mode 100644 index 9be10792..00000000 --- a/examples/rocksdb-cluster/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "rocksdb-demo" -version = "0.2.0" -edition = "2024" - -[dependencies] -d-engine = { path = "../../d-engine", features = ["rocksdb"] } -# d-engine = "0.1.4" - -bytes = "1.10" -prost = { version = "0.13", default-features = false } -metrics-exporter-prometheus = "0.17.2" -tokio = { version = "1", features = ["rt-multi-thread"] } -tracing = { version = "0.1" } -tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] } -tracing-appender = "0.2" -async-trait = "0.1.89" -bincode = "2.0.1" diff --git a/examples/rocksdb-cluster/Makefile b/examples/rocksdb-cluster/Makefile deleted file mode 100644 index 6bffb191..00000000 --- a/examples/rocksdb-cluster/Makefile +++ /dev/null @@ -1,118 +0,0 @@ -# Makefile for DEngine cluster operations - -.PHONY: build start-cluster clean clean-log-db help \ - start-node1 start-node2 start-node3 \ - perf-node1 perf-node2 perf-node3 perf-cluster -.DEFAULT_GOAL := help - -# =============================== -# Build Targets -# =============================== -build: - @echo "Building release binary..." - cargo build --release --jobs 4 - -# =============================== -# Cluster Management (Normal Mode) -# =============================== -start-node1: - @echo "Starting Node 1..." - CONFIG_PATH=config/n1 \ - NODE_ID=1 \ - DB_PATH="./db/1" \ - LOG_DIR="./logs/1" \ - METRICS_PORT=8081 \ - RUST_LOG=rocksdb_demo=warn,d_engine=warn,timing=warn \ - RUST_BACKTRACE=1 \ - ./target/release/rocksdb-demo - -start-node2: - @echo "Starting Node 2..." - CONFIG_PATH=config/n2 \ - NODE_ID=2 \ - DB_PATH="./db/2" \ - LOG_DIR="./logs/2" \ - METRICS_PORT=8082 \ - RUST_LOG=rocksdb_demo=warn,d_engine=warn,timing=warn \ - ./target/release/rocksdb-demo - -start-node3: - @echo "Starting Node 3..." - CONFIG_PATH=config/n3 \ - NODE_ID=3 \ - DB_PATH="./db/3" \ - LOG_DIR="./logs/3" \ - METRICS_PORT=8083 \ - RUST_LOG=rocksdb_demo=warn,d_engine=warn,timing=warn \ - ./target/release/rocksdb-demo - -start-cluster: clean build - @echo "Starting 3-node cluster in parallel..." - $(MAKE) -j3 start-node1 start-node2 start-node3 - - -# =============================== -# Performance Profiling with Samply -# =============================== -# Each target runs a node under `samply` profiler and outputs a .json profile - -perf-node1: - @echo "Profiling Node 1 with samply..." - CONFIG_PATH=config/n1 \ - NODE_ID=1 \ - DB_PATH="./db/1" \ - LOG_DIR="./logs/1" \ - METRICS_PORT=8081 \ - RUST_LOG=rocksdb_demo=warn,d_engine=warn,timing=warn \ - RUST_BACKTRACE=1 \ - samply record -o ./samply_reports/1.profile.json -P 3001 ./target/release/rocksdb-demo - -perf-node2: - @echo "Profiling Node 2 with samply..." - CONFIG_PATH=config/n2 \ - NODE_ID=2 \ - DB_PATH="./db/2" \ - LOG_DIR="./logs/2" \ - METRICS_PORT=8082 \ - RUST_LOG=rocksdb_demo=warn,d_engine=warn,timing=warn \ - samply record -o ./samply_reports/2.profile.json -P 3002 ./target/release/rocksdb-demo - -perf-node3: - @echo "Profiling Node 3 with samply..." - CONFIG_PATH=config/n3 \ - NODE_ID=3 \ - DB_PATH="./db/3" \ - LOG_DIR="./logs/3" \ - METRICS_PORT=8083 \ - RUST_LOG=rocksdb_demo=warn,d_engine=warn,timing=warn \ - samply record -o ./samply_reports/3.profile.json -P 3003 ./target/release/rocksdb-demo - -perf-cluster: clean build - @echo "Starting 3-node cluster under samply profiling..." - $(MAKE) -j3 perf-node1 perf-node2 perf-node3 - -# =============================== -# Utilities -# =============================== -clean: - @echo "Cleaning build artifacts..." - cargo clean - rm -rf logs/* - rm -rf db/* - rm -rf samply_reports/* - -clean-log-db: - @echo "Cleaning build artifacts..." - rm -rf logs/* - rm -rf db/* - -help: - @echo "DEngine Cluster Management Commands:" - @echo " build - Build release binary" - @echo " start-node1..3 - Start individual cluster nodes" - @echo " start-cluster - Start all 3 nodes in parallel" - @echo " perf-node1..3 - Run individual nodes under samply profiler" - @echo " perf-cluster - Run full 3-node cluster under samply profiling" - @echo " clean - Remove build artifacts, logs, and profiles" - @echo " clean-log-db - Remove only logs and database files" - @echo " help - Show this help message" diff --git a/examples/rocksdb-cluster/config/n1.toml b/examples/rocksdb-cluster/config/n1.toml deleted file mode 100644 index b8ce95bb..00000000 --- a/examples/rocksdb-cluster/config/n1.toml +++ /dev/null @@ -1,57 +0,0 @@ -[cluster] -node_id = 1 -listen_address = "0.0.0.0:9081" -initial_cluster = [ - { id = 1, address = "0.0.0.0:9081", role = 1, status = 2 }, - { id = 2, address = "0.0.0.0:9082", role = 1, status = 2 }, - { id = 3, address = "0.0.0.0:9083", role = 1, status = 2 }, -] -db_root_dir = "./db" -log_dir = "./logs" - -[raft] -general_raft_timeout_duration_in_ms = 100 - - -[raft.commit_handler] -batch_size = 5000 - -[raft.replication] -rpc_append_entries_in_batch_threshold = 5000 - -[raft.persistence] -strategy = "MemFirst" -# strategy = "DiskFirst" -flush_policy = { Batch = { threshold = 1000, interval_ms = 100 } } -# flush_policy = "Immediate" - -[raft.snapshot] -enable = false -max_log_entries_before_snapshot = 10000 -snapshot_cool_down_since_last_check = { secs = 60 } -snapshots_dir = "./snapshots/" -retained_log_entries = 3 - -# == Network Control Plane (voting, heartbeat, etc.) == -[network.control] -concurrency_limit = 20 # Lower control plane concurrency is recommended -max_concurrent_streams = 128 -connection_window_size = 2_097_152 # 2MB is sufficient (to prevent memory overflow) - -tcp_keepalive_in_secs = 60 # Closer to native behavior -http2_keep_alive_interval_in_secs = 10 -http2_keep_alive_timeout_in_secs = 5 -max_frame_size = 16_777_215 # Default value is acceptable - -# == Network Data Plane (append_entries, etc.) == -[network.data] -connect_timeout_in_ms = 100 # Slow is fine, ensure the connection is established -request_timeout_in_ms = 300 # Log synchronization may take a long time. -concurrency_limit = 30 # High concurrency supports data replication. -max_concurrent_streams = 256 # Sufficient; higher values may be counterproductive. -connection_window_size = 4_194_304 # Increase the buffer size to support batch data. - -tcp_keepalive_in_secs = 60 -http2_keep_alive_interval_in_secs = 10 -http2_keep_alive_timeout_in_secs = 5 -max_frame_size = 16_777_215 diff --git a/examples/rocksdb-cluster/config/n2.toml b/examples/rocksdb-cluster/config/n2.toml deleted file mode 100644 index 9a4b0352..00000000 --- a/examples/rocksdb-cluster/config/n2.toml +++ /dev/null @@ -1,56 +0,0 @@ -[cluster] -node_id = 2 -listen_address = "0.0.0.0:9082" -initial_cluster = [ - { id = 1, address = "0.0.0.0:9081", role = 1, status = 2 }, - { id = 2, address = "0.0.0.0:9082", role = 1, status = 2 }, - { id = 3, address = "0.0.0.0:9083", role = 1, status = 2 }, -] -db_root_dir = "./db" -log_dir = "./logs" - - -[raft] -general_raft_timeout_duration_in_ms = 100 - -[raft.commit_handler] -batch_size = 5000 - -[raft.replication] -rpc_append_entries_in_batch_threshold = 5000 - -[raft.persistence] -strategy = "MemFirst" -# strategy = "DiskFirst" -flush_policy = { Batch = { threshold = 1000, interval_ms = 100 } } -# flush_policy = "Immediate" - -[raft.snapshot] -enable = false -max_log_entries_before_snapshot = 10000 -snapshot_cool_down_since_last_check = { secs = 60 } -snapshots_dir = "./snapshots/" -retained_log_entries = 3 - - -# == Network Control Plane (voting, heartbeat, etc.) == -[network.control] -concurrency_limit = 20 # Lower control plane concurrency is recommended -max_concurrent_streams = 128 -tcp_keepalive_in_secs = 60 # Closer to native behavior -http2_keep_alive_interval_in_secs = 10 -http2_keep_alive_timeout_in_secs = 5 -max_frame_size = 16_777_215 # Default value is acceptable -connection_window_size = 2_097_152 # 2MB is sufficient (to prevent memory overflow) - -# == Network Data Plane (append_entries, etc.) == -[network.data] -connect_timeout_in_ms = 100 # Slow is fine, ensure the connection is established -request_timeout_in_ms = 300 # Log synchronization may take a long time. -concurrency_limit = 30 # High concurrency supports data replication. -max_concurrent_streams = 256 # Sufficient; higher values may be counterproductive. -tcp_keepalive_in_secs = 60 -http2_keep_alive_interval_in_secs = 10 -http2_keep_alive_timeout_in_secs = 5 -max_frame_size = 16_777_215 -connection_window_size = 4_194_304 # Increase the buffer size to support batch data. diff --git a/examples/rocksdb-cluster/config/n3.toml b/examples/rocksdb-cluster/config/n3.toml deleted file mode 100644 index 5e1de4a2..00000000 --- a/examples/rocksdb-cluster/config/n3.toml +++ /dev/null @@ -1,56 +0,0 @@ -[cluster] -node_id = 3 -listen_address = "0.0.0.0:9083" -initial_cluster = [ - { id = 1, address = "0.0.0.0:9081", role = 1, status = 2 }, - { id = 2, address = "0.0.0.0:9082", role = 1, status = 2 }, - { id = 3, address = "0.0.0.0:9083", role = 1, status = 2 }, -] -db_root_dir = "./db" -log_dir = "./logs" - -[raft] -general_raft_timeout_duration_in_ms = 100 - - -[raft.commit_handler] -batch_size = 5000 - -[raft.replication] -rpc_append_entries_in_batch_threshold = 5000 - -[raft.persistence] -strategy = "MemFirst" -# strategy = "DiskFirst" -flush_policy = { Batch = { threshold = 1000, interval_ms = 100 } } -# flush_policy = "Immediate" - - -[raft.snapshot] -enable = false -max_log_entries_before_snapshot = 10000 -snapshot_cool_down_since_last_check = { secs = 60 } -snapshots_dir = "./snapshots/" -retained_log_entries = 3 - -# == Network Control Plane (voting, heartbeat, etc.) == -[network.control] -concurrency_limit = 20 # Lower control plane concurrency is recommended -max_concurrent_streams = 128 -tcp_keepalive_in_secs = 60 # Closer to native behavior -http2_keep_alive_interval_in_secs = 10 -http2_keep_alive_timeout_in_secs = 5 -max_frame_size = 16_777_215 # Default value is acceptable -connection_window_size = 2_097_152 # 2MB is sufficient (to prevent memory overflow) - -# == Network Data Plane (append_entries, etc.) == -[network.data] -connect_timeout_in_ms = 100 # Slow is fine, ensure the connection is established -request_timeout_in_ms = 300 # Log synchronization may take a long time. -concurrency_limit = 30 # High concurrency supports data replication. -max_concurrent_streams = 256 # Sufficient; higher values may be counterproductive. -tcp_keepalive_in_secs = 60 -http2_keep_alive_interval_in_secs = 10 -http2_keep_alive_timeout_in_secs = 5 -max_frame_size = 16_777_215 -connection_window_size = 4_194_304 # Increase the buffer size to support batch data. diff --git a/examples/rocksdb-cluster/src/main.rs b/examples/rocksdb-cluster/src/main.rs deleted file mode 100644 index b0928990..00000000 --- a/examples/rocksdb-cluster/src/main.rs +++ /dev/null @@ -1,138 +0,0 @@ -use d_engine::NodeBuilder; -use d_engine::{RocksDBStateMachine, RocksDBStorageEngine}; -use std::env; -use std::error::Error; -use std::fs::OpenOptions; -use std::path::{Path, PathBuf}; -use std::sync::Arc; -use std::time::Duration; -use tokio::signal::unix::signal; -use tokio::signal::unix::SignalKind; -use tokio::sync::watch; -use tracing::{error, info}; -use tracing_appender::non_blocking::WorkerGuard; -use tracing_subscriber::layer::SubscriberExt; -use tracing_subscriber::util::SubscriberInitExt; -use tracing_subscriber::{EnvFilter, Layer}; - -#[tokio::main] -async fn main() { - // Parse configuration - let node_id = env::var("NODE_ID") - .expect("NODE_ID required") - .parse::() - .expect("Invalid NODE_ID"); - - let db_path = env::var("DB_PATH").unwrap_or_else(|_| format!("/tmp/data/node-{node_id}")); - - let log_dir = env::var("LOG_DIR") - .map_err(|_| "LOG_DIR environment variable not set") - .expect("Set log dir successfully."); - - let metrics_port: u16 = env::var("METRICS_PORT") - .map(|v| v.parse::().expect("METRICS_PORT must be a valid port")) - .unwrap_or(9000); // default 9000 if not set - - // Initialize observability - let _guard = init_observability(log_dir); - - // Initializing Shutdown Signal - let (graceful_tx, graceful_rx) = watch::channel(()); - - // Start the server (wait for its initialization to complete) - let server_handler = tokio::spawn(start_dengine_server( - PathBuf::from(db_path), - graceful_rx.clone(), - )); - - // Wait for the server to initialize (adjust the waiting time according to the actual logic) - tokio::time::sleep(Duration::from_secs(1)).await; - - // Start Prometheus metrics server - let metrics_handle = tokio::spawn(start_metrics_server(metrics_port)); - - // Monitor shutdown signals - let shutdown_handler = tokio::spawn(graceful_shutdown(graceful_tx)); - - // Wait for all tasks to complete (or error) - let (_server_result, _metrics_result, _shutdown_result) = - tokio::join!(server_handler, metrics_handle, shutdown_handler); -} - -async fn start_dengine_server( - db_path: PathBuf, - graceful_rx: watch::Receiver<()>, -) { - let storage_engine = Arc::new(RocksDBStorageEngine::new(db_path.join("storage")).unwrap()); - let state_machine = Arc::new(RocksDBStateMachine::new(db_path.join("state_machine")).unwrap()); - // Start Node - let node = NodeBuilder::new(None, graceful_rx.clone()) - .storage_engine(storage_engine) - .state_machine(state_machine) - .start() - .await - .expect("start node failed."); - - // Start Node - if let Err(e) = node.run().await { - error!("node stops: {:?}", e); - } else { - info!("node stops."); - } - - println!("Exiting program."); -} - -pub fn init_observability(log_dir: String) -> Result> { - let log_file = open_file_for_append(Path::new(&log_dir).join("d.log")).unwrap(); - - let (non_blocking, guard) = tracing_appender::non_blocking(log_file); - let base_subscriber = tracing_subscriber::fmt::layer() - .with_writer(non_blocking) - .with_filter(EnvFilter::from_default_env()); - tracing_subscriber::registry().with(base_subscriber).init(); - Ok(guard) -} - -async fn start_metrics_server(port: u16) { - // Start Prometheus exporter with dynamic port - println!("Metrics server will start at http://0.0.0.0:{port}/metrics",); - metrics_exporter_prometheus::PrometheusBuilder::new() - .with_http_listener(([0, 0, 0, 0], port)) - .install() - .expect("failed to start Prometheus metrics exporter"); -} - -async fn graceful_shutdown(graceful_tx: watch::Sender<()>) { - info!("Monitoring shutdown signal ..."); - let mut sigint = signal(SignalKind::interrupt()).unwrap(); - let mut sigterm = signal(SignalKind::terminate()).unwrap(); - tokio::select! { - _ = sigint.recv() => { - info!("SIGINT detected."); - }, - _ = sigterm.recv() => { - info!("SIGTERM detected."); - }, - _ = tokio::signal::ctrl_c() => { - info!("Ctrl+C detected."); - } - } - - graceful_tx.send(()).unwrap(); - - info!("Shutdown completed"); -} - -fn open_file_for_append(path: PathBuf) -> Result> { - // Create parent directories if they don't exist - if let Some(parent) = path.parent() { - if parent != Path::new("") { - std::fs::create_dir_all(parent)?; - } - } - - let log_file = OpenOptions::new().append(true).create(true).open(&path)?; - - Ok(log_file) -} diff --git a/examples/service-discovery-embedded/README.md b/examples/service-discovery-embedded/README.md index 711f95de..60d0b9dd 100644 --- a/examples/service-discovery-embedded/README.md +++ b/examples/service-discovery-embedded/README.md @@ -1,6 +1,12 @@ # Service Discovery - Embedded Mode -Demonstrates **embedded** service discovery β€” each application node embeds d-engine directly. +Demonstrates d-engine's **Watch API in embedded mode** β€” ultra-low latency change notifications through in-process communication. + +**What you'll learn:** + +- Using Watch API with LocalKvClient (no gRPC overhead) +- Sub-millisecond read and watch latency +- Embedded d-engine architecture patterns ## Architecture (Consul-style) @@ -47,13 +53,26 @@ The demo will: 3. Show how to read with LocalKvClient 4. Demonstrate in-process watch notifications +## Key Concepts Demonstrated + +### Primary: Embedded Watch API + +- **LocalKvClient** β€” In-process KV operations with <0.1ms latency +- **Watch notifications** β€” Microsecond-level event delivery +- **Zero serialization** β€” Direct memory access, no gRPC overhead + +### Secondary: Embedded Architecture + +- Each app instance embeds d-engine (similar to Consul) +- Raft replication between embedded nodes +- Service discovery as a practical use case + ## When to Use Embedded Mode -- **Ultra-low latency required** β€” DNS/service discovery needs <1ms response -- **Each app instance is a Raft participant** β€” Similar to Consul architecture -- **Rust-only** β€” LocalKvClient is Rust-native, no gRPC serialization +- **Ultra-low latency required** β€” Watch events need microsecond response +- **Rust-only applications** β€” LocalKvClient is Rust-native +- **Co-located architecture** β€” App and storage in same process ## Related - [Standalone Example](../service-discovery-standalone/) β€” gRPC client mode -- [Service Discovery Pattern](../../d-engine-docs/src/docs/client_guide/service-discovery-pattern.md) diff --git a/examples/service-discovery-standalone/README.md b/examples/service-discovery-standalone/README.md index 1386293f..e2036ecd 100644 --- a/examples/service-discovery-standalone/README.md +++ b/examples/service-discovery-standalone/README.md @@ -1,6 +1,12 @@ # Service Discovery Example -Demonstrates using d-engine for **service discovery** β€” a Type 2 use case from [user personas](../../d-engine-docs/src/docs/client_guide/service-discovery-pattern.md). +Demonstrates d-engine's **Watch API** through a practical service discovery use case. + +**What you'll learn:** + +- How to use the Watch API for real-time change notifications +- Implementing the read-then-watch pattern +- Building reactive systems without polling ## Architecture @@ -50,19 +56,27 @@ cargo run --bin admin -- unregister --name api-gateway --instance node1 ## Components -| Binary | Purpose | -|--------|---------| -| `admin` | Registers/unregisters service endpoints | +| Binary | Purpose | +| --------- | ----------------------------------------- | +| `admin` | Registers/unregisters service endpoints | | `watcher` | Watches for service changes via Watch API | ## Key Concepts Demonstrated +### Primary: Watch API Usage + 1. **Watch API** β€” Real-time change notifications without polling -2. **EventualConsistency** β€” Fastest reads from any node -3. **Read-then-Watch Pattern** β€” Read current state, then watch for changes +2. **Read-then-Watch Pattern** β€” Read current state, then watch for changes +3. **Event Handling** β€” Process PUT/DELETE events reactively + +### Secondary: Service Discovery Pattern + +- Using d-engine as a service registry +- EventualConsistency reads for fast lookups +- Key-value schema design for services ## Related Documentation -- [Service Discovery Pattern](../../d-engine-docs/src/docs/client_guide/service-discovery-pattern.md) -- [Watch Feature Guide](../../d-engine-docs/src/docs/server_guide/watch-feature.md) -- [Read Consistency Guide](../../d-engine-docs/src/docs/client_guide/read_consistency.md) +- Service Discovery Pattern (coming soon on docs.rs) +- [Watch Feature Guide](https://docs.rs/d-engine/latest/d_engine/docs/server_guide/watch_feature/index.html) +- [Read Consistency Guide](https://docs.rs/d-engine/latest/d_engine/docs/client_guide/read_consistency/index.html) diff --git a/examples/single-node-expansion/README.md b/examples/single-node-expansion/README.md index 2e600d19..81b5ba7f 100644 --- a/examples/single-node-expansion/README.md +++ b/examples/single-node-expansion/README.md @@ -175,7 +175,7 @@ make clean-logs # Remove logs and DB only ## Further Reading -- [Single-Node Expansion Guide](../../d-engine-docs/src/docs/examples/single-node-expansion.md) - Detailed explanation +- [Single-Node Expansion Guide](https://docs.rs/d-engine/latest/d_engine/docs/examples/single_node_expansion/index.html) - Detailed explanation --- diff --git a/examples/sled-cluster/src/sled_engine_test.rs b/examples/sled-cluster/src/sled_engine_test.rs index 4bdd2c96..f327af88 100644 --- a/examples/sled-cluster/src/sled_engine_test.rs +++ b/examples/sled-cluster/src/sled_engine_test.rs @@ -1,11 +1,11 @@ use super::*; use bytes::{Bytes, BytesMut}; -use d_engine::{ - common::{entry_payload::Payload, Entry, EntryPayload}, - write_command::{write_command::Operation, WriteCommand}, - LogStore, Result, StorageEngine, +use d_engine::{LogStore, Result, StorageEngine}; +use d_engine_proto::client::{ + WriteCommand, + write_command::{Insert, Operation}, }; -use d_engine_proto::client::write_command::Insert; +use d_engine_proto::common::{Entry, EntryPayload, entry_payload::Payload}; use prost::Message; use std::sync::Arc; use tempfile::TempDir; diff --git a/examples/sled-cluster/src/sled_state_machine.rs b/examples/sled-cluster/src/sled_state_machine.rs index d6c51a17..7d71ad70 100644 --- a/examples/sled-cluster/src/sled_state_machine.rs +++ b/examples/sled-cluster/src/sled_state_machine.rs @@ -6,12 +6,12 @@ use bincode::config; use bytes::Bytes; use d_engine::{ Result, SnapshotError, StateMachine, StorageError, - common::{Entry, LogId, entry_payload::Payload}, - storage::SnapshotMetadata, - write_command::{ + client::{ WriteCommand, write_command::{Delete, Insert, Operation}, }, + common::{Entry, LogId, entry_payload::Payload}, + server_storage::SnapshotMetadata, }; use parking_lot::Mutex; use prost::Message; diff --git a/examples/three-nodes-cluster/Makefile b/examples/three-nodes-cluster/Makefile index 70241046..75aa0e89 100644 --- a/examples/three-nodes-cluster/Makefile +++ b/examples/three-nodes-cluster/Makefile @@ -22,32 +22,32 @@ build: # Cluster Management (Normal Mode) # =============================== start-node1: - @echo "Starting Node 1..." - CONFIG_PATH=config/n1 \ + @echo "πŸš€ Starting Node 1..." + @CONFIG_PATH=config/n1 \ DB_PATH="./db/1" \ LOG_DIR="./logs/1" \ METRICS_PORT=8081 \ RUST_LOG=demo=$(LOG_LEVEL),d_engine=$(LOG_LEVEL),timing=$(LOG_LEVEL) \ RUST_BACKTRACE=1 \ - ./target/release/demo + ./target/release/demo 2>&1 | sed 's/^/[Node1] /' start-node2: - @echo "Starting Node 2..." - CONFIG_PATH=config/n2 \ + @echo "πŸš€ Starting Node 2..." + @CONFIG_PATH=config/n2 \ DB_PATH="./db/2" \ LOG_DIR="./logs/2" \ METRICS_PORT=8082 \ RUST_LOG=demo=$(LOG_LEVEL),d_engine=$(LOG_LEVEL),timing=$(LOG_LEVEL) \ - ./target/release/demo + ./target/release/demo 2>&1 | sed 's/^/[Node2] /' start-node3: - @echo "Starting Node 3..." - CONFIG_PATH=config/n3 \ + @echo "πŸš€ Starting Node 3..." + @CONFIG_PATH=config/n3 \ DB_PATH="./db/3" \ LOG_DIR="./logs/3" \ METRICS_PORT=8083 \ RUST_LOG=demo=$(LOG_LEVEL),d_engine=$(LOG_LEVEL),timing=$(LOG_LEVEL) \ - ./target/release/demo + ./target/release/demo 2>&1 | sed 's/^/[Node3] /' start-cluster: clean build diff --git a/examples/three-nodes-cluster/src/main.rs b/examples/three-nodes-cluster/src/main.rs index 55693b6e..d1aa6f8e 100644 --- a/examples/three-nodes-cluster/src/main.rs +++ b/examples/three-nodes-cluster/src/main.rs @@ -90,6 +90,11 @@ async fn start_dengine_server( config_path: String, graceful_rx: watch::Receiver<()>, ) { + println!("╔════════════════════════════════════════╗"); + println!("β•‘ d-engine Node Starting... β•‘"); + println!("β•‘ Config: {config_path:<28} β•‘"); + println!("β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•"); + // StandaloneServer with explicit config path // Blocks until shutdown signal received if let Err(e) = StandaloneServer::run_with(&config_path, graceful_rx).await {