use {
crate::{
NetworkId,
PeerId,
groups::{Bonds, Cursor, GroupId, Index, StateMachine, Storage, Term},
primitives::{EncodeError, UniqueId, sealed::Sealed},
},
core::task::{Context, Poll},
serde::{Serialize, de::DeserializeOwned},
};
pub trait StateSync: Send + 'static {
type Machine: StateMachine;
type Message: StateSyncMessage;
type Provider: StateSyncProvider<Owner = Self>;
type Session: StateSyncSession<Owner = Self>;
fn signature(&self) -> UniqueId;
fn create_provider(&self, cx: &dyn SyncContext<Self>) -> Self::Provider;
fn create_session(
&self,
cx: &mut dyn SyncSessionContext<Self>,
position: Cursor,
leader_commit: Index,
entries: Vec<(Command<Self>, Term)>,
) -> Self::Session;
}
pub trait StateSyncProvider: Send + 'static {
type Owner: StateSync;
fn poll(
&mut self,
_: &mut Context<'_>,
_: &mut dyn SyncProviderContext<Self::Owner>,
) -> Poll<()> {
Poll::Pending
}
fn receive(
&mut self,
message: Message<Self::Owner>,
sender: PeerId,
cx: &mut dyn SyncProviderContext<Self::Owner>,
) -> Result<(), Message<Self::Owner>>;
#[inline]
fn safe_to_prune_prefix(
&self,
_: &mut dyn SyncProviderContext<Self::Owner>,
) -> Option<Index> {
None
}
#[inline]
fn committed(
&mut self,
_: Cursor,
_: &mut dyn SyncProviderContext<Self::Owner>,
) {
}
}
pub trait StateSyncSession: Send + 'static {
type Owner: StateSync;
fn poll(
&mut self,
cx: &mut Context<'_>,
driver: &mut dyn SyncSessionContext<Self::Owner>,
) -> Poll<Cursor>;
fn receive(
&mut self,
message: Message<Self::Owner>,
sender: PeerId,
cx: &mut dyn SyncSessionContext<Self::Owner>,
);
fn buffer(
&mut self,
position: Cursor,
entries: Vec<(Command<Self::Owner>, Term)>,
cx: &mut dyn SyncSessionContext<Self::Owner>,
);
}
pub trait SyncContext<S: StateSync>: Sealed {
fn state_machine(&self) -> &S::Machine;
fn state_machine_mut(&mut self) -> &mut S::Machine;
fn log(&self) -> &dyn Storage<Command<S>>;
fn log_mut(&mut self) -> &mut dyn Storage<Command<S>>;
fn committed(&self) -> Cursor;
fn local_id(&self) -> PeerId;
fn group_id(&self) -> GroupId;
fn network_id(&self) -> NetworkId;
fn send_to(
&mut self,
peer: PeerId,
message: S::Message,
) -> Result<(), EncodeError>;
fn broadcast(
&mut self,
message: S::Message,
) -> Result<Vec<PeerId>, EncodeError>;
fn bonds(&self) -> Bonds<S::Machine>;
}
pub trait SyncSessionContext<S: StateSync>: SyncContext<S> {
fn leader(&self) -> PeerId;
fn set_committed(&mut self, position: Cursor);
}
pub trait SyncProviderContext<S: StateSync>: SyncContext<S> {
fn leader(&self) -> Option<PeerId>;
#[inline]
fn is_leader(&self) -> bool {
self.leader() == Some(self.local_id())
}
fn feed_command(&mut self, command: Command<S>) -> Result<(), Command<S>>;
}
pub trait StateSyncMessage:
Clone + Serialize + DeserializeOwned + Send + Sync + 'static
{
}
impl<T> StateSyncMessage for T where
T: Clone + Serialize + DeserializeOwned + Send + Sync + 'static
{
}
pub type Machine<S> = <S as StateSync>::Machine;
pub type Message<S> = <S as StateSync>::Message;
pub type Command<S> = <Machine<S> as StateMachine>::Command;
pub type Session<S> = <S as StateSync>::Session;
pub type Provider<S> = <S as StateSync>::Provider;