Skip to content

Commit 9dbbe14

Browse files
committed
Fix: check_is_leader() should return at once if encountering StorageError
Refactor: ExtractFatal is not used any more. Fatal error should only be raised by Command executor, no more by API handler. There is no need to extract Fatal error from an API error.
1 parent 9ac025d commit 9dbbe14

File tree

2 files changed

+10
-41
lines changed

2 files changed

+10
-41
lines changed

openraft/src/core/raft_core.rs

+10-13
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ use crate::error::ChangeMembershipError;
4444
use crate::error::CheckIsLeaderError;
4545
use crate::error::ClientWriteError;
4646
use crate::error::EmptyMembership;
47-
use crate::error::ExtractFatal;
4847
use crate::error::Fatal;
4948
use crate::error::ForwardToLeader;
5049
use crate::error::InProgress;
@@ -234,28 +233,27 @@ impl<C: RaftTypeConfig, N: RaftNetworkFactory<C>, S: RaftStorage<C>> RaftCore<C,
234233
pub(super) async fn handle_check_is_leader_request(
235234
&mut self,
236235
tx: RaftRespTx<(), CheckIsLeaderError<C::NodeId, C::Node>>,
237-
) {
236+
) -> Result<(), StorageError<C::NodeId>> {
238237
// Setup sentinel values to track when we've received majority confirmation of leadership.
239238

240239
let em = self.engine.state.membership_state.effective();
241240
let mut granted = btreeset! {self.id};
242241

243242
if em.is_quorum(granted.iter()) {
244243
let _ = tx.send(Ok(()));
245-
return;
244+
return Ok(());
246245
}
247246

248247
// Spawn parallel requests, all with the standard timeout for heartbeats.
249248
let mut pending = FuturesUnordered::new();
250249

251-
let voter_progresses = if let Some(l) = &self.engine.internal_server_state.leading() {
250+
let voter_progresses = {
251+
let l = &self.engine.internal_server_state.leading().unwrap();
252252
l.progress
253253
.iter()
254254
.filter(|(id, _v)| l.progress.is_voter(id) == Some(true))
255255
.copied()
256256
.collect::<Vec<_>>()
257-
} else {
258-
unreachable!("it has to be a leader!!!");
259257
};
260258

261259
for (target, progress) in voter_progresses {
@@ -329,10 +327,8 @@ impl<C: RaftTypeConfig, N: RaftNetworkFactory<C>, S: RaftStorage<C>> RaftCore<C,
329327
// request.
330328
if let AppendEntriesResponse::HigherVote(vote) = data {
331329
let res = self.engine.vote_handler().handle_message_vote(&vote);
332-
if let Err(e) = self.run_engine_commands::<Entry<C>>(&[]).await.extract_fatal() {
333-
let _ = tx.send(Err(e.into()));
334-
return;
335-
}
330+
self.run_engine_commands::<Entry<C>>(&[]).await?;
331+
336332
if let Err(e) = res {
337333
// simply ignore stale responses
338334
tracing::warn!(target = display(target), "vote {vote} rejected: {e}");
@@ -341,7 +337,7 @@ impl<C: RaftTypeConfig, N: RaftNetworkFactory<C>, S: RaftStorage<C>> RaftCore<C,
341337
// we are no longer leader so error out early
342338
if !self.engine.state.is_leader(&self.engine.config.id) {
343339
self.reject_with_forward_to_leader(tx);
344-
return;
340+
return Ok(());
345341
}
346342
}
347343

@@ -350,7 +346,7 @@ impl<C: RaftTypeConfig, N: RaftNetworkFactory<C>, S: RaftStorage<C>> RaftCore<C,
350346
let mem = &self.engine.state.membership_state.effective();
351347
if mem.is_quorum(granted.iter()) {
352348
let _ = tx.send(Ok(()));
353-
return;
349+
return Ok(());
354350
}
355351
}
356352

@@ -362,6 +358,7 @@ impl<C: RaftTypeConfig, N: RaftNetworkFactory<C>, S: RaftStorage<C>> RaftCore<C,
362358
got: granted,
363359
}
364360
.into()));
361+
Ok(())
365362
}
366363

367364
/// Add a new node to the cluster as a learner, bringing it up-to-speed, and then responding
@@ -1193,7 +1190,7 @@ impl<C: RaftTypeConfig, N: RaftNetworkFactory<C>, S: RaftStorage<C>> RaftCore<C,
11931190
}
11941191
RaftMsg::CheckIsLeaderRequest { tx } => {
11951192
if self.engine.state.is_leader(&self.engine.config.id) {
1196-
self.handle_check_is_leader_request(tx).await;
1193+
self.handle_check_is_leader_request(tx).await?;
11971194
} else {
11981195
self.reject_with_forward_to_leader(tx);
11991196
}

openraft/src/error.rs

-28
Original file line numberDiff line numberDiff line change
@@ -33,34 +33,6 @@ where NID: NodeId
3333
Stopped,
3434
}
3535

36-
/// Extract Fatal from a Result.
37-
///
38-
/// Fatal will shutdown the raft and needs to be dealt separately,
39-
/// such as StorageError.
40-
pub trait ExtractFatal<NID>
41-
where
42-
Self: Sized,
43-
NID: NodeId,
44-
{
45-
fn extract_fatal(self) -> Result<Self, Fatal<NID>>;
46-
}
47-
48-
impl<NID, T, E> ExtractFatal<NID> for Result<T, E>
49-
where
50-
NID: NodeId,
51-
E: TryInto<Fatal<NID>> + Clone,
52-
{
53-
fn extract_fatal(self) -> Result<Self, Fatal<NID>> {
54-
if let Err(e) = &self {
55-
let fatal = e.clone().try_into();
56-
if let Ok(f) = fatal {
57-
return Err(f);
58-
}
59-
}
60-
Ok(self)
61-
}
62-
}
63-
6436
// TODO: not used, remove
6537
#[derive(Debug, Clone, thiserror::Error, derive_more::TryInto)]
6638
#[derive(PartialEq, Eq)]

0 commit comments

Comments
 (0)