openraft/type_config.rs
1//! Define the configuration of types used by the Raft, such as [`NodeId`], log [`Entry`], etc.
2//!
3//! [`NodeId`]: `RaftTypeConfig::NodeId`
4//! [`Entry`]: `RaftTypeConfig::Entry`
5
6pub(crate) mod util;
7
8use std::fmt::Debug;
9
10pub use util::TypeConfigExt;
11
12use crate::entry::FromAppData;
13use crate::entry::RaftEntry;
14use crate::raft::responder::Responder;
15use crate::AppData;
16use crate::AppDataResponse;
17use crate::AsyncRuntime;
18use crate::Node;
19use crate::NodeId;
20use crate::OptionalSend;
21use crate::OptionalSync;
22
23/// Configuration of types used by the [`Raft`] core engine.
24///
25/// The (empty) implementation structure defines request/response types, node ID type
26/// and the like. Refer to the documentation of associated types for more information.
27///
28/// ## Note
29///
30/// Since Rust cannot automatically infer traits for various inner types using this config
31/// type as a parameter, this trait simply uses all the traits required for various types
32/// as its supertraits as a workaround. To ease the declaration, the macro
33/// `declare_raft_types` is provided, which can be used to declare the type easily.
34///
35/// Example:
36/// ```ignore
37/// openraft::declare_raft_types!(
38/// pub TypeConfig:
39/// D = ClientRequest,
40/// R = ClientResponse,
41/// NodeId = u64,
42/// Node = openraft::BasicNode,
43/// Entry = openraft::Entry<TypeConfig>,
44/// SnapshotData = Cursor<Vec<u8>>,
45/// AsyncRuntime = openraft::TokioRuntime,
46/// );
47/// ```
48/// [`Raft`]: crate::Raft
49pub trait RaftTypeConfig:
50 Sized + OptionalSend + OptionalSync + Debug + Clone + Copy + Default + Eq + PartialEq + Ord + PartialOrd + 'static
51{
52 /// Application-specific request data passed to the state machine.
53 type D: AppData;
54
55 /// Application-specific response data returned by the state machine.
56 type R: AppDataResponse;
57
58 /// A Raft node's ID.
59 type NodeId: NodeId;
60
61 /// Raft application level node data
62 type Node: Node;
63
64 /// Raft log entry, which can be built from an AppData.
65 type Entry: RaftEntry<Self::NodeId, Self::Node> + FromAppData<Self::D>;
66
67 /// Snapshot data for exposing a snapshot for reading & writing.
68 ///
69 /// See the [storage chapter of the guide][sto] for details on log compaction / snapshotting.
70 ///
71 /// To use a more generic snapshot transmission, you can use the `generic-snapshot-data`
72 /// feature. Enabling this feature allows you to send any type of snapshot data, by removing the
73 /// `AsyncWrite + AsyncSeek` bounds on the `SnapshotData` type.
74 /// This is useful when a snapshot is a more complex data structure than a single file.
75 /// See the [generic snapshot
76 /// data](crate::docs::feature_flags#feature-flag-generic-snapshot-data) chapter for
77 /// details.
78 ///
79 /// [sto]: crate::docs::getting_started#3-implement-raftlogstorage-and-raftstatemachine
80 #[cfg(not(feature = "generic-snapshot-data"))]
81 type SnapshotData: tokio::io::AsyncRead
82 + tokio::io::AsyncWrite
83 + tokio::io::AsyncSeek
84 + OptionalSend
85 + Unpin
86 + 'static;
87
88 /// Snapshot data for exposing a snapshot for reading & writing.
89 ///
90 /// See the [storage chapter of the guide][sto] for details on log compaction / snapshotting.
91 ///
92 /// [sto]: crate::docs::getting_started#3-implement-raftlogstorage-and-raftstatemachine
93 #[cfg(feature = "generic-snapshot-data")]
94 type SnapshotData: OptionalSend + 'static;
95
96 /// Asynchronous runtime type.
97 type AsyncRuntime: AsyncRuntime;
98
99 /// Send the response or error of a client write request([`WriteResult`]).
100 ///
101 /// For example, return [`WriteResult`] the to the caller of [`Raft::client_write`], or send to
102 /// some application defined channel.
103 ///
104 /// [`Raft::client_write`]: `crate::raft::Raft::client_write`
105 /// [`WriteResult`]: `crate::raft::message::ClientWriteResult`
106 type Responder: Responder<Self>;
107}
108
109#[allow(dead_code)]
110/// Type alias for types used in `RaftTypeConfig`.
111pub(crate) mod alias {
112 use crate::raft::responder::Responder;
113 use crate::RaftTypeConfig;
114
115 pub type DOf<C> = <C as RaftTypeConfig>::D;
116 pub type ROf<C> = <C as RaftTypeConfig>::R;
117 pub type NodeIdOf<C> = <C as RaftTypeConfig>::NodeId;
118 pub type NodeOf<C> = <C as RaftTypeConfig>::Node;
119 pub type EntryOf<C> = <C as RaftTypeConfig>::Entry;
120 pub type SnapshotDataOf<C> = <C as RaftTypeConfig>::SnapshotData;
121 pub type AsyncRuntimeOf<C> = <C as RaftTypeConfig>::AsyncRuntime;
122 pub type ResponderOf<C> = <C as RaftTypeConfig>::Responder;
123 pub type ResponderReceiverOf<C> = <ResponderOf<C> as Responder<C>>::Receiver;
124
125 pub type JoinErrorOf<C> = <AsyncRuntimeOf<C> as crate::AsyncRuntime>::JoinError;
126 pub type JoinHandleOf<C, T> = <AsyncRuntimeOf<C> as crate::AsyncRuntime>::JoinHandle<T>;
127 pub type SleepOf<C> = <AsyncRuntimeOf<C> as crate::AsyncRuntime>::Sleep;
128 pub type InstantOf<C> = <AsyncRuntimeOf<C> as crate::AsyncRuntime>::Instant;
129 pub type TimeoutErrorOf<C> = <AsyncRuntimeOf<C> as crate::AsyncRuntime>::TimeoutError;
130 pub type TimeoutOf<C, R, F> = <AsyncRuntimeOf<C> as crate::AsyncRuntime>::Timeout<R, F>;
131 pub type OneshotSenderOf<C, T> = <AsyncRuntimeOf<C> as crate::AsyncRuntime>::OneshotSender<T>;
132 pub type OneshotReceiverErrorOf<C> = <AsyncRuntimeOf<C> as crate::AsyncRuntime>::OneshotReceiverError;
133 pub type OneshotReceiverOf<C, T> = <AsyncRuntimeOf<C> as crate::AsyncRuntime>::OneshotReceiver<T>;
134
135 // Usually used types
136 pub type LogIdOf<C> = crate::LogId<NodeIdOf<C>>;
137 pub type VoteOf<C> = crate::Vote<NodeIdOf<C>>;
138 pub type LeaderIdOf<C> = crate::LeaderId<NodeIdOf<C>>;
139 pub type CommittedLeaderIdOf<C> = crate::CommittedLeaderId<NodeIdOf<C>>;
140}