use actix::prelude::*;
use crate::{
AppData, AppDataResponse, AppError, NodeId,
messages::ClientError,
};
pub struct InitWithConfig {
pub members: Vec<NodeId>,
}
impl InitWithConfig {
pub fn new(members: Vec<NodeId>) -> Self {
Self{members}
}
}
impl Message for InitWithConfig {
type Result = Result<(), InitWithConfigError>;
}
#[derive(Debug)]
pub enum InitWithConfigError {
Internal,
NotAllowed,
}
impl std::fmt::Display for InitWithConfigError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
InitWithConfigError::Internal => write!(f, "An error internal to Raft has taken place."),
InitWithConfigError::NotAllowed => write!(f, "Submission of this command to this node is not allowed due to the state of the node."),
}
}
}
impl std::error::Error for InitWithConfigError {}
pub struct ProposeConfigChange<D: AppData, R: AppDataResponse, E: AppError> {
pub(crate) add_members: Vec<NodeId>,
pub(crate) remove_members: Vec<NodeId>,
marker_data: std::marker::PhantomData<D>,
marker_res: std::marker::PhantomData<R>,
marker_error: std::marker::PhantomData<E>,
}
impl<D: AppData, R: AppDataResponse, E: AppError> ProposeConfigChange<D, R, E> {
pub fn new(add_members: Vec<NodeId>, remove_members: Vec<NodeId>) -> Self {
Self{add_members, remove_members, marker_data: std::marker::PhantomData, marker_res: std::marker::PhantomData, marker_error: std::marker::PhantomData}
}
}
impl<D: AppData, R: AppDataResponse, E: AppError> Message for ProposeConfigChange<D, R, E> {
type Result = Result<(), ProposeConfigChangeError<D, R, E>>;
}
#[derive(Debug)]
pub enum ProposeConfigChangeError<D: AppData, R: AppDataResponse, E: AppError> {
ClientError(ClientError<D, R, E>),
InoperableConfig,
Internal,
NodeNotLeader(Option<NodeId>),
Noop,
}
impl<D: AppData, R: AppDataResponse, E: AppError> std::fmt::Display for ProposeConfigChangeError<D, R, E> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ProposeConfigChangeError::ClientError(err) => write!(f, "{}", err),
ProposeConfigChangeError::InoperableConfig => write!(f, "The given config would leave the cluster in an inoperable state."),
ProposeConfigChangeError::Internal => write!(f, "An error internal to Raft has taken place."),
ProposeConfigChangeError::NodeNotLeader(leader_opt) => write!(f, "The handling node is not the Raft leader. Tracked value for cluster leader: {:?}", leader_opt),
ProposeConfigChangeError::Noop => write!(f, "The proposed config change would have no effect, this is a no-op."),
}
}
}
impl<D: AppData, R: AppDataResponse, E: AppError> std::error::Error for ProposeConfigChangeError<D, R, E> {}