Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
166 commits
Select commit Hold shift + click to select a range
d8bd658
feat #43: When a Raft leader is elected, it should first send an empt…
JoshuaChi Apr 19, 2025
8fb91b3
Feature/59 benchmark (#72)
JoshuaChi Apr 20, 2025
2f97f6c
chore(ci) #73: prepare release for v0.1.2
JoshuaChi Apr 20, 2025
1756873
Merge branch 'main' into develop
JoshuaChi Apr 22, 2025
e53ba82
feat #79: Snapshot feature, Learner join cluster feature and develope…
JoshuaChi Sep 3, 2025
729e100
feat #79: optimize v0.1.3 CHANGELOG
JoshuaChi Sep 3, 2025
cebfdbb
Merge branch 'main' into develop
JoshuaChi Sep 3, 2025
0a057c8
fix #133: Example project: File/RocksDB storage engines can fail to s…
JoshuaChi Sep 7, 2025
bd44015
fix #133: fix fmt
JoshuaChi Sep 7, 2025
265c250
fix #133: fix fmt
JoshuaChi Sep 7, 2025
2e88aae
fix #133: fix fmt
JoshuaChi Sep 7, 2025
598f011
fix #133: update REAMDE
JoshuaChi Sep 7, 2025
68de4c7
feat #135: Enable tokio via three-nodes-cluster example
JoshuaChi Sep 17, 2025
3fe4cdc
feat #135: Enable tokio_metrics via three-nodes-cluster example
JoshuaChi Sep 17, 2025
f7911c1
feat #135: Enable tokio_metrics via three-nodes-cluster example
JoshuaChi Sep 18, 2025
4e30171
feat #138: v0.1.4 - target 100K throughput
JoshuaChi Oct 13, 2025
b03a606
fix #145: fix Bytes compatible bugs in examples folder
JoshuaChi Oct 14, 2025
f3f3430
fix #150: type issue
JoshuaChi Oct 14, 2025
32cc365
fix #151: fix mmap bug
JoshuaChi Oct 14, 2025
0713943
fix #152: Update README by introduce new feature from v0.1.4
JoshuaChi Oct 15, 2025
ff1e251
fix #153: fix code review feedback
JoshuaChi Oct 15, 2025
8659663
fix #154: code review feedback
JoshuaChi Oct 15, 2025
901008f
fix #155: fix code review feedback
JoshuaChi Oct 15, 2025
a3c314d
fix #156: fix code review feedback
JoshuaChi Oct 15, 2025
58f97dc
fix #157: fix code review feedback
JoshuaChi Oct 15, 2025
f145325
fix #158, #159: fix code review feedback
JoshuaChi Oct 16, 2025
7e0d96e
fix #164: fix code review bug
JoshuaChi Oct 16, 2025
b3e119e
fix #161: fix code review feedback
JoshuaChi Oct 16, 2025
9ea5116
fix #164: fix doc issues
JoshuaChi Oct 16, 2025
2169613
Merge branch 'main' into develop
JoshuaChi Oct 18, 2025
be93d34
feat #167: workspace structure (#175)
JoshuaChi Nov 5, 2025
d9636d1
feat #172: Feature ttl support (#176)
JoshuaChi Nov 12, 2025
2569af0
fix #172: format code to pass rustfmt checks
JoshuaChi Nov 12, 2025
e1143d0
fix #172: Replace tokio-tar with astral-tokio-tar to resolve CVE-2025…
JoshuaChi Nov 13, 2025
803400a
fix #172: Resolve Tokio runtime nesting issue in TTL benchmark
JoshuaChi Nov 13, 2025
69279ee
fix #172: Resolve clippy unused_unit warnings and improve Makefile be…
JoshuaChi Nov 13, 2025
56f1410
feat #174: Implement lock-free Watch mechanism for real-time key moni…
JoshuaChi Nov 25, 2025
6c90b57
feat #179: Implement single-node cluster support for dynamic expansio…
JoshuaChi Nov 26, 2025
97fab24
feat #182: Add EmbeddedEngine API with leader election notification &…
JoshuaChi Dec 1, 2025
ec736ab
doc #185: Add service discovery pattern guide for DNS/registry use cases
JoshuaChi Dec 3, 2025
c653330
doc #187: Restructure examples documentation to match folder structure
JoshuaChi Dec 3, 2025
635b3cd
doc #187: Fix broken benchmark documentation link in three-nodes-clus…
JoshuaChi Dec 3, 2025
5ed3544
docs #192: add comprehensive read consistency documentation
JoshuaChi Dec 4, 2025
e0b4142
feat(bench) #193: add --key-space parameter for hot-key testing
JoshuaChi Dec 5, 2025
9220e58
perf(watch) #194: Skip protobuf decoding when no active watchers exist
JoshuaChi Dec 5, 2025
0312010
docs(bench) #195: Update v0.2.0 benchmark report with accurate v0.1.4…
JoshuaChi Dec 5, 2025
208df8b
feat #196: Implement Watch feature with gRPC streaming and examples
JoshuaChi Dec 11, 2025
6d8ce99
docs #204: Prepare v0.2.0 release documentation
JoshuaChi Dec 11, 2025
2381550
fix #204: Suppress rustls-pemfile unmaintained warning in dependency …
JoshuaChi Dec 11, 2025
4163f9a
fix #204: Fix flaky test and update documentation for v0.2.0
JoshuaChi Dec 11, 2025
9123484
fix #205: Enable graceful shutdown during node startup phase
JoshuaChi Dec 12, 2025
0f94d9e
docs #204: Fix documentation links and optimize workspace doc generation
JoshuaChi Dec 12, 2025
52e1e74
doc #204: Simplify feature flags and add use-case guidance
JoshuaChi Dec 13, 2025
f7b0418
chore #204: Prepare v0.2.0 release with workspace cleanup
JoshuaChi Dec 13, 2025
793ab4c
style #204: Fix import ordering to comply with rustfmt stable
JoshuaChi Dec 13, 2025
faa62b3
fix #204: Address code review feedback for v0.2.0 release
JoshuaChi Dec 13, 2025
1b55a6f
perf #208: eliminate redundant async calls in leader write hot path
JoshuaChi Dec 13, 2025
86a1278
fix #204: update both fields in update_cluster_metadata to prevent st…
JoshuaChi Dec 13, 2025
bcf2239
fix #204: Increase election RPC timeout to fix flaky tests
JoshuaChi Dec 13, 2025
f601479
ci #204: Support docs as alias for doc in commit message validation
JoshuaChi Dec 14, 2025
b8eb206
docs #204: Prepare v0.2.0 for HN launch - simplify docs and set expec…
JoshuaChi Dec 14, 2025
8204c5c
docs #204: Fix documentation links and add integration mode quick sta…
JoshuaChi Dec 16, 2025
6e0c610
refactor(raft) #209: Architecture review - consolidate v0.2.0 improve…
JoshuaChi Dec 31, 2025
84c1539
doc #224: Fix rustdoc links and improve documentation generation
JoshuaChi Dec 31, 2025
40d7c47
doc #224: Fix markdown table formatting and typo in documentation
JoshuaChi Dec 31, 2025
c4a6e1f
doc #225: Prepare multi-crate publishing documentation and configurat…
JoshuaChi Jan 1, 2026
ea370fe
chore #227: Merge branch 'main' into develop
JoshuaChi Jan 1, 2026
0db60ee
doc #227: fix working directory and version requirements
JoshuaChi Jan 1, 2026
1d42cb4
chore #228: Merge branch 'main' into develop
JoshuaChi Jan 1, 2026
dcae76c
fix #228: Critical: Inconsistent reads in single-node mode (#229)
JoshuaChi Jan 1, 2026
4b8e0cb
perf #228: Optimize wait_applied with fast path and comprehensive tests
JoshuaChi Jan 2, 2026
72a3775
chore: Release v0.2.1 & Merge branch 'main' into develop
JoshuaChi Jan 2, 2026
8df8b08
docs #232: Fix docs.rs build and optimize feature configuration
JoshuaChi Jan 3, 2026
eadcde3
docs #232: Update vision and philosophy in README and overview
JoshuaChi Jan 4, 2026
76ecc3e
perf #233: Add embedded mode benchmark and expose node_id for testing
JoshuaChi Jan 4, 2026
75a37b8
feat #234: feat: Add cluster state APIs to EmbeddedEngine for HA depl…
JoshuaChi Jan 4, 2026
dad5461
fix #235: Snapshot purge fails in single-node cluster with NoPeersAva…
JoshuaChi Jan 5, 2026
3c70c63
fix #235: Snapshot purge fails in single-node cluster with NoPeersAva…
JoshuaChi Jan 5, 2026
163f7a9
fix #235: Snapshot purge fails in single-node cluster with NoPeersAva…
JoshuaChi Jan 5, 2026
a4dd343
feat #233: Benchmark embedded mode performance and clarify standalone…
JoshuaChi Jan 5, 2026
ef0c131
test(bench) #233: fix LeaseRead test mock and add embedded mode bench…
JoshuaChi Jan 5, 2026
4c1156a
ci #237: fix GitHub Actions disk space issue and improve CI workflow
JoshuaChi Jan 5, 2026
0176abf
perf #236: Optimize LinearizableRead to avoid unnecessary waiting on …
JoshuaChi Jan 6, 2026
df0edf7
test #236: Improve test stability and fix CI build
JoshuaChi Jan 6, 2026
f0f7801
feat #236: Implement ReadIndex batching for LinearizableRead optimiza…
JoshuaChi Jan 8, 2026
1b932e9
refactor #236: Unify leadership verification and eliminate redundant …
JoshuaChi Jan 9, 2026
ace603f
refactor #236: Migrate LinearizableRead tests to core and strengthen …
JoshuaChi Jan 9, 2026
a650ef7
perf(bench) #236: Fix test hang + optimize benchmarks
JoshuaChi Jan 9, 2026
fbf63da
test #236: Consolidate client read tests into leader_state_client_rea…
JoshuaChi Jan 9, 2026
5be0100
fix #241: start_with() fails when CONFIG_PATH is not set
JoshuaChi Jan 10, 2026
222d10b
refactor #234: Simplify Makefile and improve documentation workflow
JoshuaChi Jan 10, 2026
ca21713
feat(storage) #242: Implement comprehensive durability test suite and…
JoshuaChi Jan 11, 2026
8dbfba7
fix(storage) #243: Add read protection during snapshot restoration
JoshuaChi Jan 11, 2026
96f3d49
test(snapshot) #243: Add Learner snapshot concurrent replication test
JoshuaChi Jan 11, 2026
9954d4e
refactor #244: refactor integration tests
JoshuaChi Jan 12, 2026
fcb8882
fix #240: Address code review feedback for v0.2.2 release
JoshuaChi Jan 12, 2026
83be905
Merge pull request #240 from deventlab/feature/236_readindex
JoshuaChi Jan 12, 2026
264c0f3
fix #240: Fix watch benchmark and allow bincode unmaintained warning
JoshuaChi Jan 12, 2026
6108f8f
chore #240: Prepare v0.2.2 release
JoshuaChi Jan 12, 2026
5c4138e
Feature/245 refactor server ut (#247)
JoshuaChi Jan 14, 2026
9a13bc7
Merge branch 'main' into develop
JoshuaChi Jan 16, 2026
429246b
Merge branch 'main' into develop
JoshuaChi Jan 23, 2026
74c8934
refactor #258: Unify client API with CAS support
JoshuaChi Jan 24, 2026
87a1c11
refactor #258: Replace bool succeeded with WriteResult message
JoshuaChi Jan 24, 2026
a06f08a
refactor #258: Add Deref to Client for direct method access
JoshuaChi Jan 24, 2026
7685051
refactor #258: Remove LocalClientError, use ClientApiError directly
JoshuaChi Jan 24, 2026
f46078c
refactor #258: Rename test directory local_kv_client to embedded_client
JoshuaChi Jan 24, 2026
2af93e4
refactor #258: Unify watch() API and finalize client architecture
JoshuaChi Jan 24, 2026
f9d7ddc
refactor #258: rename StandaloneServer to StandaloneEngine for consis…
JoshuaChi Jan 24, 2026
f22937e
docs #258: update StandaloneServer to StandaloneEngine in documentation
JoshuaChi Jan 24, 2026
5b5bbf2
fix #258: fix compilation errors after CAS tests and API refactoring
JoshuaChi Jan 24, 2026
2ca1a97
refactor #258: remove client.kv() calls in all tests
JoshuaChi Jan 24, 2026
d990dcc
refactor #258: migrate embedded_client_operations to use EmbeddedEngine
JoshuaChi Jan 24, 2026
8c12f6e
refactor #258: migrate linearizable_read_consistency_embedded to Embe…
JoshuaChi Jan 24, 2026
180ff9d
refactor #258: migrate linearizable_read_batching_embedded to Embedde…
JoshuaChi Jan 24, 2026
59c273f
test #258: add P0 error handling tests for ClientApiError
JoshuaChi Jan 24, 2026
2bcf620
refactor #258: make EmbeddedEngine thread-safe with Arc wrapper
JoshuaChi Jan 25, 2026
29add44
refactor #263: Return actual CAS operation results to clients (Raft p…
JoshuaChi Jan 26, 2026
051ae94
refactor #263: Return actual CAS operation results to clients (Raft p…
JoshuaChi Jan 26, 2026
94875f3
refactor #258: Unify read consistency control + remove CommitHandlerC…
JoshuaChi Jan 26, 2026
ac3511b
refactor #263: Implement FatalError event propagation for SM Worker f…
JoshuaChi Jan 26, 2026
d1c43fc
refactor #266: Implement drain-based batch architecture for client co…
JoshuaChi Feb 8, 2026
f4ffc53
fix #266: Correct BatchBuffer::take_with_trigger() to return first N …
JoshuaChi Feb 9, 2026
bbac2ee
refactor #258: Split raft_test.rs into modular test structure with ca…
JoshuaChi Feb 9, 2026
cbe9dfb
perf #258: Optimize drain-based batch architecture with parameter tuning
JoshuaChi Feb 9, 2026
4212d14
perf #258: Encapsulate backpressure metrics for zero-cost abstraction…
JoshuaChi Feb 9, 2026
9f6a7a4
perf #258: Encapsulate backpressure metrics for zero-cost abstraction…
JoshuaChi Feb 9, 2026
c6f6a72
refactor #267: Optimize batch processing with deferred RaftRequestWit…
JoshuaChi Feb 10, 2026
23d2476
perf #268: Unify write and linearizable read into single RPC, extract…
JoshuaChi Feb 13, 2026
a732d4c
fix #268: Fix SM Worker channel handling in CommitHandler tests and o…
JoshuaChi Feb 13, 2026
44edb51
fix #268: Remove incorrect BatchBuffer tests that assumed take_all() …
JoshuaChi Feb 13, 2026
fca39f6
perf #268: Batch I/O in FileStateMachine and fix read consistency pol…
JoshuaChi Feb 14, 2026
c724923
fix #268: Propagate persist error in lease_background_cleanup to prev…
JoshuaChi Feb 14, 2026
f7428ff
fix #269: Route client.get() with no policy to leader to match server…
JoshuaChi Feb 14, 2026
a40eaa9
fix #269: Do not crash node when ClusterConf response receiver is dro…
JoshuaChi Feb 14, 2026
3c815dd
fix #258: Move snapshot check to ApplyCompleted handler in all role s…
JoshuaChi Feb 14, 2026
cad3a16
fix #270: Add snapshot trigger to Follower/Learner ApplyCompleted han…
JoshuaChi Feb 15, 2026
ec65932
refactor #271: Simplify log purge to independent per-node model (Raft…
JoshuaChi Feb 15, 2026
220c5ea
fix(raft) #272: eliminate linearizable read self-blocking via event-d…
JoshuaChi Feb 16, 2026
4e59df4
refactor #272: remove time_threshold_ms from ReadBatchingConfig
JoshuaChi Feb 16, 2026
b18eea4
fix #272: use tmpdir and TCP-ready wait in test_join_cluster_scenario2
JoshuaChi Feb 16, 2026
9f00028
feat #273: enforce MSRV 1.85 via Cargo.toml, README, and CI verification
JoshuaChi Feb 17, 2026
3904940
fix(snapshot) #270: Follower/Learner snapshot trigger blocked by Lead…
JoshuaChi Feb 17, 2026
fbf59b4
refactor #267: Replace BatchBuffer<ProposeTuple> with SoA ProposeBatc…
JoshuaChi Feb 17, 2026
b62f4ae
fix(ci) #273: Update CI dependencies for Rust 1.85 MSRV compatibility
JoshuaChi Feb 17, 2026
2c60c33
fix(ci) #273: Downgrade cargo-nextest to 0.9.100 for Rust 1.85 compat…
JoshuaChi Feb 17, 2026
f5f80de
fix #273: Raise CI scalability test threshold to 500x for disk I/O sp…
JoshuaChi Feb 18, 2026
87fe32d
docs #259: update embedded bench guide with make clean step and auto-…
JoshuaChi Feb 18, 2026
bf89218
fix #273: ignore flaky scalability tests, revert CI threshold to 100x
JoshuaChi Feb 18, 2026
33be4ff
fix #274: update CONTRIBUTING.md target branch from develop to main
JoshuaChi Feb 18, 2026
ee1dd6a
fix #258: resolve flaky tests under parallel test load
JoshuaChi Feb 18, 2026
5dff3b5
refactor #258: clarify pending_reads drain loop with explicit key col…
JoshuaChi Feb 18, 2026
9dba319
fix #258: log done signal write error and update CHANGELOG for v0.2.3
JoshuaChi Feb 18, 2026
788c276
ci #273: skip commit check for develop→main and pin cargo-deny to 0.18.3
JoshuaChi Feb 18, 2026
a2cba7b
ci #277: remove cargo-deny version pin, stable toolchain supports latest
JoshuaChi Feb 18, 2026
e9ff737
ci #277: force stable toolchain in dependency-audit via RUSTUP_TOOLCH…
JoshuaChi Feb 18, 2026
9ceef49
ci #277: revert MSRV to 1.88, remove 1.85 compatibility workarounds
JoshuaChi Feb 18, 2026
47469b8
ci #277: upgrade bytes to 1.11.1, remove unused OpenSSL license entry
JoshuaChi Feb 18, 2026
55e7ab3
ci #277: pin cargo-nextest to 0.9.114 for MSRV 1.88 compatibility
JoshuaChi Feb 18, 2026
8586b08
docs #277: add v0.2.3 benchmark report with AWS 3-node vs etcd compar…
JoshuaChi Feb 18, 2026
b31d0e3
fix #277: notify pending_reads and sender on FatalError and lease ver…
JoshuaChi Feb 18, 2026
0b19e76
fix #277: address PR code review feedback
JoshuaChi Feb 18, 2026
a1ab14c
fix #277: remove incorrect debug_assert_eq in broadcast_watch_events
JoshuaChi Feb 18, 2026
e910ccf
fix #277: address remaining PR review feedback
JoshuaChi Feb 18, 2026
0a6a66c
fix #277: fix flaky failover tests under parallel test load
JoshuaChi Feb 18, 2026
69cfee3
fix #277: tighten test assertions per PR review
JoshuaChi Feb 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/commit-message-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:

jobs:
validate-commits:
if: github.head_ref != 'develop'
runs-on: ubuntu-latest
permissions:
contents: read
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/dependency-audit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ on:
jobs:
audit:
runs-on: ubuntu-latest
env:
RUSTUP_TOOLCHAIN: stable
steps:
- uses: actions/checkout@v4

Expand Down
50 changes: 46 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,48 @@ All notable changes to this project will be documented in this file.

---

## [Unreleased v0.2.3]

### Added

- **CompareAndSwap (CAS) Operation** (#258): Atomic compare-and-swap primitive for distributed coordination
- Use cases: Distributed locks, leader election, optimistic updates
- API: `client.compare_and_swap(key, expected_value, new_value)`
- Performance: No additional protocol round-trips; latency is comparable to regular writes in most workloads

Comment thread
JoshuaChi marked this conversation as resolved.
### Changed

- **Unified Client API** (#258): Merged KV and cluster operations into single `ClientApi` trait
- **Breaking**: `KvClient` → `ClientApi`, `KvError` → `ClientApiError`
- Simplifies developer experience (single trait for all operations)
- Both `GrpcClient` and `EmbeddedClient` implement unified interface

- **WriteResult Message** (#258): Replaced `bool succeeded` with `WriteResult` message
- Improves API extensibility (reserved fields for version tracking)
- Better type safety for future features

- **Simplified Error Handling** (#258): Removed `LocalClientError`, use `ClientApiError` directly
- Unified error type across embedded and standalone clients
- Less boilerplate (no intermediate error type conversion)
- Clearer error semantics for users

- **Drain-based batch architecture** (#266): Replaced timeout-driven batching with drain-on-arrival pattern
- Low load: near-zero wait (eliminated ~1ms timeout penalty)
- High load: natural batching, significant throughput improvement
- Embedded: linearizable read +92%, lease/eventual read +62% vs v0.2.2
- See [bench report v0.2.3](benches/reports/v0.2.3/bench_report_v0.2.3.md)

- **Default PersistenceStrategy changed: `MemFirst` → `DiskFirst`** (#268): Raft protocol compliance
- **Breaking**: Add `persistence_strategy = "MemFirst"` to `[raft.persistence]` config to restore prior behavior

### Migration Notes

- Replace `KvClient` with `ClientApi` in trait bounds
- Replace `KvError` with `ClientApiError` in error handling
- Update imports: `use d_engine::client::ClientApi;`

---

## [v0.2.2] - 2026-01-12 [✅ Released]

### 🎯 Key Improvements
Expand Down Expand Up @@ -71,7 +113,7 @@ while let Some(event) = watcher.next().await {

**Performance**: Lock-free, <0.1ms notification latency

#### StandaloneServer - One-Line Deployment
#### StandaloneEngine - One-Line Deployment

**Use Case**: Independent server process (production deployment)
**API**: `run(shutdown_rx)` uses env config, `run_with(config_path, shutdown_rx)` uses explicit config
Expand All @@ -81,9 +123,9 @@ while let Some(event) = watcher.next().await {

**Use Case**: Embed d-engine in your Rust application
**API**: `start()` uses env config, `start_with(config_path)` uses explicit config, `start_custom(...)` for advanced usage
**Benefit**: Zero gRPC overhead via LocalKvClient (<0.1ms latency)
**Benefit**: Zero gRPC overhead via EmbeddedClient (<0.1ms latency)

#### LocalKvClient - Zero-Overhead Embedded Access
#### EmbeddedClient - Zero-Overhead Embedded Access

**When**: Your app and d-engine in same process
**Benefit**: Skip gRPC serialization, direct memory access (<0.1ms)
Expand All @@ -95,7 +137,7 @@ while let Some(event) = watcher.next().await {

- `examples/quick-start/` - 5-minute single-node setup
- `examples/single-node-expansion/` - Dynamic 1→3 node scaling
- `examples/service-discovery-embedded/` - LocalKvClient zero-overhead access
- `examples/service-discovery-embedded/` - EmbeddedClient zero-overhead access
- `examples/service-discovery-standalone/` - Watch API pattern

---
Expand Down
12 changes: 11 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,17 @@ make test # Run all tests with nextest (fast, parallel)

- Features: `feature/<ticket-number>_<short-description>`
- Bug fixes: `bug/<ticket-number>_<short-description>`
- Target `develop` branch for all PRs
- Target `main` branch for all PRs

### Keeping Your PR Up-to-Date

If `main` has moved forward since you created your branch, rebase before requesting review:

```bash
git fetch upstream
git rebase upstream/main
git push --force-with-lease
```

### Code Quality

Expand Down
22 changes: 11 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ authors = ["Joshua Chi <joshokn@gmail.com>"]
homepage = "https://github.com/deventlab/d-engine"
repository = "https://github.com/deventlab/d-engine"
license = "MIT OR Apache-2.0"
rust-version = "1.88"
Comment thread
JoshuaChi marked this conversation as resolved.

[workspace.dependencies]
d-engine-proto = { path = "./d-engine-proto", version = "0.2.2" }
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ and pluggable storage backends. Start with one node, scale to a cluster when nee
### New in v0.2 🎉

- **EmbeddedEngine**: Single-node start, scale to 3-node cluster when needed
- **LocalKvClient**: Zero-overhead in-process access (<0.1ms latency)
- **EmbeddedClient**: Zero-overhead in-process access (<0.1ms latency)
- **Watch API**: Real-time key change notifications (config updates, service discovery)
- **TTL/Lease**: Automatic key expiration for distributed locks and session management
- **Modular Workspace**: Feature flags (`client`/`server`) - depend only on what you need
Expand Down
1 change: 1 addition & 0 deletions benches/embedded-bench/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ all-tests: build
$(BENCH_BIN) \
--mode local \
--batch \
--clients 1000 \
--key-size $(KEY_SIZE) \
--value-size $(VALUE_SIZE) \
$(SEQUENTIAL) \
Expand Down
8 changes: 4 additions & 4 deletions benches/embedded-bench/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ make all-tests

`embedded-bench` tests d-engine in embedded mode with three operation modes:

- **`local`**: Direct in-process benchmark using `LocalKvClient` (zero-copy, baseline performance)
- **`local`**: Direct in-process benchmark using `EmbeddedClient` (zero-copy, baseline performance)
- **`server`**: HTTP server exposing KV operations via REST API
- **`client`**: HTTP client for testing with load balancer (e.g., HAProxy)

Expand Down Expand Up @@ -60,7 +60,7 @@ This design mirrors how `standalone-bench` (Standalone) distributes requests via

### Test A: Embedded Pure Mode (Baseline)

Direct in-process benchmark measuring `LocalKvClient` performance without network overhead.
Direct in-process benchmark measuring `EmbeddedClient` performance without network overhead.

```

Expand All @@ -72,7 +72,7 @@ Direct in-process benchmark measuring `LocalKvClient` performance without networ
│ │ embedded- │ │ embedded- │ │ embedded- │ │
│ │ bench n1 │ │ bench n2 │ │ bench n3 │ │
│ ├──────────────┤ ├──────────────┤ ├──────────────┤ │
│ │ LocalKvClient│ │ LocalKvClient│ │ LocalKvClient│ │
│ │EmbeddedClient│ │EmbeddedClient│ │EmbeddedClient│ │
│ │ (internal │ │ (internal │ │ (internal │ │
│ │ benchmark) │ │ benchmark) │ │ benchmark) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
Expand Down Expand Up @@ -279,7 +279,7 @@ Expected performance comparison chain:

```
Standalone < Embedded+HAProxy < Embedded Pure Mode
(gRPC) (HTTP+HAProxy) (LocalKvClient)
(gRPC) (HTTP+HAProxy) (EmbeddedClient)
```

| Mode | Overhead | Use Case |
Expand Down
9 changes: 7 additions & 2 deletions benches/embedded-bench/config/n1.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@ initial_cluster = [
db_root_dir = "./data/n1"
log_dir = "./logs"

[raft]
general_raft_timeout_duration_in_ms = 10000 # 10 sec
[raft.batching]
# Maximum number of commands to accumulate in a single batch during drain operations
max_batch_size = 500

[raft.metrics]
enable_backpressure = false
enable_batch = false

[raft.snapshot]
enable = false
8 changes: 6 additions & 2 deletions benches/embedded-bench/config/n2.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ initial_cluster = [
db_root_dir = "./data/n2"
log_dir = "./logs"

[raft.batching]
# Maximum number of commands to accumulate in a single batch during drain operations
max_batch_size = 500

[raft]
general_raft_timeout_duration_in_ms = 10000 # 10 sec
[raft.metrics]
enable_backpressure = false
enable_batch = false

[raft.snapshot]
enable = false
8 changes: 6 additions & 2 deletions benches/embedded-bench/config/n3.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ initial_cluster = [
db_root_dir = "./data/n3"
log_dir = "./logs"

[raft.batching]
# Maximum number of commands to accumulate in a single batch during drain operations
max_batch_size = 500

[raft]
general_raft_timeout_duration_in_ms = 10000 # 10 sec
[raft.metrics]
enable_backpressure = false
enable_batch = false

[raft.snapshot]
enable = false
Binary file not shown.
24 changes: 22 additions & 2 deletions benches/embedded-bench/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,9 @@ async fn run_local_benchmark(cli: Cli) {
println!("Leader elected: {}", leader_info.leader_id);
println!("Node ID: {}", engine.node_id());

// Signal file used to coordinate follower auto-shutdown in batch mode
let done_signal_path = "/tmp/embedded-bench-done";

// Setup Ctrl+C handler
let (shutdown_tx, mut shutdown_rx) = tokio::sync::watch::channel(());

Expand All @@ -474,14 +477,31 @@ async fn run_local_benchmark(cli: Cli) {

// Check if running in batch mode
if cli.batch {
// Clean up any leftover signal file from a previous run
let _ = std::fs::remove_file(done_signal_path);

if engine.is_leader() {
run_batch_tests(&engine, &cli).await;
// Signal followers to auto-shutdown
if let Err(e) = std::fs::write(done_signal_path, "done") {
eprintln!("Failed to write done signal: {e}");
}
} else {
println!(
"This node is Follower, keeping cluster membership alive during batch tests..."
);
println!("Press Ctrl+C to shutdown.");
let _ = shutdown_rx.changed().await;
println!("Will auto-shutdown when leader completes benchmarks.");
loop {
tokio::select! {
_ = shutdown_rx.changed() => break,
_ = tokio::time::sleep(Duration::from_secs(1)) => {
if std::path::Path::new(done_signal_path).exists() {
println!("Benchmark completed, shutting down follower.");
break;
}
}
}
}
}
} else {
// Single test mode (original behavior)
Expand Down
Loading