Add stemedb-cluster crate implementing horizontal scaling: - SWIM-based membership protocol for node discovery and failure detection - Consistent hashing (jump hash) for subject-to-shard routing - Range management with dynamic split (>64MB) and merge (<20MB) operations - Stateless HTTP gateway for client request routing via axum - Meta-range gossip merge for cluster-wide metadata propagation Includes restrictive CORS policy, proper error propagation from routing, replica cache invalidation on node failure, and 84 tests (57 unit + 27 integration). Raft MV coordination deferred per design decision. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
101 lines
2.6 KiB
Rust
101 lines
2.6 KiB
Rust
//! Error types for the cluster layer.
|
|
|
|
use thiserror::Error;
|
|
|
|
/// Errors that can occur during cluster operations.
|
|
#[derive(Debug, Error)]
|
|
pub enum ClusterError {
|
|
/// Membership operation failed.
|
|
#[error("Membership error: {0}")]
|
|
Membership(String),
|
|
|
|
/// Node not found in cluster.
|
|
#[error("Node not found: {0}")]
|
|
NodeNotFound(String),
|
|
|
|
/// Sharding operation failed.
|
|
#[error("Sharding error: {0}")]
|
|
Sharding(String),
|
|
|
|
/// Shard not found.
|
|
#[error("Shard not found: {0}")]
|
|
ShardNotFound(u32),
|
|
|
|
/// No replicas available for shard.
|
|
#[error("No replicas available for shard {0}")]
|
|
NoReplicasAvailable(u32),
|
|
|
|
/// Gateway routing failed.
|
|
#[error("Gateway error: {0}")]
|
|
Gateway(String),
|
|
|
|
/// RPC communication failed.
|
|
#[error("RPC error: {0}")]
|
|
Rpc(#[from] stemedb_rpc::RpcError),
|
|
|
|
/// Sync operation failed.
|
|
#[error("Sync error: {0}")]
|
|
Sync(#[from] stemedb_sync::SyncError),
|
|
|
|
/// Storage operation failed.
|
|
#[error("Storage error: {0}")]
|
|
Storage(String),
|
|
|
|
/// Configuration error.
|
|
#[error("Configuration error: {0}")]
|
|
Config(String),
|
|
|
|
/// Network I/O error.
|
|
#[error("Network error: {0}")]
|
|
Network(String),
|
|
|
|
/// Serialization/deserialization failed.
|
|
#[error("Serialization error: {0}")]
|
|
Serialization(String),
|
|
|
|
/// Channel send/receive error.
|
|
#[error("Channel error: {0}")]
|
|
Channel(String),
|
|
|
|
/// Timeout waiting for operation.
|
|
#[error("Timeout: {0}")]
|
|
Timeout(String),
|
|
|
|
/// Internal consistency error.
|
|
#[error("Internal error: {0}")]
|
|
Internal(String),
|
|
}
|
|
|
|
impl From<stemedb_storage::error::StorageError> for ClusterError {
|
|
fn from(err: stemedb_storage::error::StorageError) -> Self {
|
|
ClusterError::Storage(err.to_string())
|
|
}
|
|
}
|
|
|
|
impl From<std::io::Error> for ClusterError {
|
|
fn from(err: std::io::Error) -> Self {
|
|
ClusterError::Network(err.to_string())
|
|
}
|
|
}
|
|
|
|
impl<T> From<tokio::sync::broadcast::error::SendError<T>> for ClusterError {
|
|
fn from(err: tokio::sync::broadcast::error::SendError<T>) -> Self {
|
|
ClusterError::Channel(format!("broadcast send failed: {err}"))
|
|
}
|
|
}
|
|
|
|
impl From<tokio::sync::broadcast::error::RecvError> for ClusterError {
|
|
fn from(err: tokio::sync::broadcast::error::RecvError) -> Self {
|
|
ClusterError::Channel(format!("broadcast recv failed: {err}"))
|
|
}
|
|
}
|
|
|
|
impl From<serde_json::Error> for ClusterError {
|
|
fn from(err: serde_json::Error) -> Self {
|
|
ClusterError::Serialization(err.to_string())
|
|
}
|
|
}
|
|
|
|
/// Result type for cluster operations.
|
|
pub type Result<T> = std::result::Result<T, ClusterError>;
|