stemedb/crates/stemedb-cluster/src/error.rs
jordan afed95fe26 feat: Multi-node cluster coordination (Phase 6C)
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>
2026-02-02 20:57:54 -07:00

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>;