use super::*;
pub struct Effect {
pub voter: Voter,
}
impl Effect {
fn state_machine(&self) -> &Read<StateMachine> {
&self.voter.state_machine
}
fn peers(&self) -> &Read<Peers> {
&self.voter.peers
}
pub async fn exec(self) -> Result<()> {
ensure!(std::matches!(
self.voter.read_election_state(),
voter::ElectionState::Leader
));
let last_membership_change_index = {
let index = self
.state_machine()
.membership_pointer
.load(Ordering::SeqCst);
ensure!(index <= self.state_machine().commit_pointer.load(Ordering::SeqCst));
index
};
let config = self
.state_machine()
.try_read_membership(last_membership_change_index)
.await?
.context(Error::BadLogState)?;
ensure!(!config.contains(&self.voter.driver.self_node_id()));
info!("step down");
self.voter
.write_election_state(voter::ElectionState::Follower);
self.peers().transfer_leadership().await?;
Ok(())
}
}