use {
crate::{
Datum,
groups::{Cursor, Term},
primitives::UniqueId,
},
serde::{Serialize, de::DeserializeOwned},
};
mod noop;
mod sync;
#[doc(hidden)]
pub use noop::NoOp;
pub use sync::*;
pub trait StateMachine: Sized + Send + Sync + 'static {
type Command: Command;
type Query: Query;
type QueryResult: QueryResult;
type StateSync: StateSync<Machine = Self>;
fn signature(&self) -> UniqueId;
fn apply(&mut self, command: Self::Command, ctx: &dyn ApplyContext);
#[inline]
fn apply_batch(
&mut self,
commands: impl IntoIterator<Item = Self::Command>,
ctx: &dyn ApplyContext,
) {
for command in commands {
self.apply(command, ctx);
}
}
fn query(&self, query: Self::Query) -> Self::QueryResult;
fn state_sync(&self) -> Self::StateSync;
#[inline]
fn leadership_preference(&self) -> LeadershipPreference {
LeadershipPreference::Normal
}
}
pub trait ApplyContext {
fn committed(&self) -> Cursor;
fn log_position(&self) -> Cursor;
fn current_term(&self) -> Term;
}
pub trait StateMachineMessage:
Clone + Send + Sync + Serialize + DeserializeOwned + 'static
{
}
impl<T> StateMachineMessage for T where
T: Clone + Send + Sync + Serialize + DeserializeOwned + 'static
{
}
pub trait Command: Datum + Sync + Clone {}
impl<T> Command for T where T: Datum + Sync + Clone {}
pub trait Query: Datum + Sync + Clone {}
impl<T> Query for T where T: Datum + Sync + Clone {}
pub trait QueryResult: Datum + Sync + Clone {}
impl<T> QueryResult for T where T: Datum + Sync + Clone {}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum LeadershipPreference {
#[default]
Normal,
Reluctant {
factor: u32,
},
Observer,
}
impl LeadershipPreference {
pub const fn reluctant() -> Self {
Self::Reluctant { factor: 3 }
}
}