| Crates.io | rabia-kvstore-example |
| lib.rs | rabia-kvstore-example |
| version | 0.4.1 |
| created_at | 2025-08-22 14:18:41.675584+00 |
| updated_at | 2025-08-22 14:18:41.675584+00 |
| description | Key-value store state machine implementation example using the Rabia SMR protocol |
| homepage | https://github.com/rabia-rs/rabia |
| repository | https://github.com/rabia-rs/rabia |
| max_upload_size | |
| id | 1806405 |
| size | 89,397 |
This example demonstrates how to build a production-grade distributed key-value store using State Machine Replication (SMR) with the Rabia consensus protocol.
The KV Store SMR demonstrates advanced SMR concepts:
The KV store implements these operations:
Set { key, value } - Store a key-value pairGet { key } - Retrieve value for a keyDelete { key } - Remove a key-value pairExists { key } - Check if a key existsListKeys - Get all keys (for debugging/monitoring)Clear - Remove all key-value pairsSize - Get current number of stored keys#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KVStoreState {
pub data: HashMap<String, String>,
pub operation_count: u64,
pub created_at: SystemTime,
pub last_modified: SystemTime,
}
// The KV store publishes change notifications
pub enum ChangeNotification {
KeySet { key: String, value: String, old_value: Option<String> },
KeyDeleted { key: String, old_value: String },
StoreCleared { key_count: usize },
}
// Clients can subscribe to changes
let subscription_id = store.subscribe_to_changes(|notification| {
println!("Key changed: {:?}", notification);
}).await;
// Implements efficient serialization for large state
fn serialize_state(&self) -> Vec<u8> {
// Uses bincode for compact binary serialization
bincode::serialize(&self.state).unwrap_or_default()
}
// Supports incremental state updates
async fn apply_command(&mut self, command: Self::Command) -> Self::Response {
let old_value = self.state.data.get(&key).cloned();
// ... apply operation ...
// Emit change notification for subscribers
if let Some(notification) = self.create_notification(&command, &old_value) {
self.notification_bus.publish(notification).await;
}
KVResult::success(response_data)
}
store.rs)High-level interface for KV operations with:
operations.rs)Defines KV operations and results:
smr_impl.rs)Core StateMachine trait implementation:
notifications.rs)Event-driven change notifications:
# Run the KV store SMR example
cargo run --bin kvstore_smr_example
# Run with multiple replicas
cargo run --bin kvstore_smr_cluster
# Run tests to see SMR behavior
cargo test -p kvstore_smr
# Run benchmarks
cargo bench --bench kvstore_performance
This pattern is ideal for:
use kvstore_smr::{KVStoreSMR, NotificationBus};
let mut kvstore = KVStoreSMR::new_with_notifications().await?;
// Subscribe to all changes
let subscription = kvstore.subscribe_to_changes().await;
// Subscribe to specific key patterns
let user_subscription = kvstore.subscribe_to_prefix("user:").await;
// Apply operations and receive notifications
kvstore.set("user:123", "john_doe").await?;
// Notification: KeySet { key: "user:123", value: "john_doe", old_value: None }
use kvstore_smr::KVOperation;
let batch_ops = vec![
KVOperation::Set { key: "key1".to_string(), value: "value1".to_string() },
KVOperation::Set { key: "key2".to_string(), value: "value2".to_string() },
KVOperation::Delete { key: "old_key".to_string() },
];
let results = kvstore.apply_commands(batch_ops).await;
// All operations applied atomically across replicas
// Create snapshot
let snapshot = kvstore.serialize_state();
// Restore from snapshot
let mut new_kvstore = KVStoreSMR::new().await?;
new_kvstore.deserialize_state(&snapshot)?;
// Verify restored state
assert_eq!(new_kvstore.size().await, original_size);
use kvstore_smr::KVStoreConfig;
let config = KVStoreConfig {
max_entries: 1_000_000, // Maximum number of keys
max_memory_bytes: 1_024_000_000, // 1GB memory limit
enable_notifications: true, // Enable change notifications
notification_buffer_size: 1000, // Notification queue size
snapshot_compression: true, // Compress snapshots
key_expiration_enabled: false, // TTL support (optional)
metrics_enabled: true, // Performance metrics
};
let kvstore = KVStoreSMR::new(config).await?;
After understanding the KV store example, explore: