use std::future::IntoFuture;
use openraft_macros::since;
use crate::RaftTypeConfig;
use crate::base::BoxFuture;
use crate::batch::Batch;
use crate::core::raft_msg::RaftMsg;
use crate::entry::EntryPayload;
use crate::errors::Fatal;
#[cfg(feature = "runtime-stats")]
use crate::raft::api::app::propose_at_now;
use crate::raft::raft_inner::RaftInner;
use crate::raft::responder::core_responder::CoreResponder;
use crate::type_config::alias::CommittedLeaderIdOf;
use crate::type_config::alias::WriteResponderOf;
#[since(version = "0.10.0")]
pub struct WriteRequest<'a, C>
where C: RaftTypeConfig
{
pub(in crate::raft) inner: &'a RaftInner<C>,
pub(in crate::raft) app_data: C::D,
pub(in crate::raft) responder: Option<CoreResponder<C>>,
pub(in crate::raft) expected_leader: Option<CommittedLeaderIdOf<C>>,
}
impl<'a, C> WriteRequest<'a, C>
where C: RaftTypeConfig
{
#[since(version = "0.10.0")]
pub fn responder(mut self, responder: WriteResponderOf<C>) -> Self {
self.responder = Some(CoreResponder::UserDefined(responder));
self
}
#[since(version = "0.10.0")]
pub fn with_leader(mut self, expected_leader: impl Into<CommittedLeaderIdOf<C>>) -> Self {
self.expected_leader = Some(expected_leader.into());
self
}
}
impl<'a, C> IntoFuture for WriteRequest<'a, C>
where C: RaftTypeConfig
{
type Output = Result<(), Fatal<C>>;
type IntoFuture = BoxFuture<'a, Self::Output>;
fn into_future(self) -> Self::IntoFuture {
Box::pin(async move {
self.inner
.send_msg(RaftMsg::ClientWrite {
payloads: Batch::of([EntryPayload::Normal(self.app_data)]),
responders: Batch::of([self.responder]),
expected_leader: self.expected_leader,
#[cfg(feature = "runtime-stats")]
proposed_at: propose_at_now::<C>(),
})
.await
})
}
}