use futures::Future;
use super::super::{Common, NextState, RoleState};
use super::{Follower, FollowerIdle, FollowerSnapshot};
use message::{Message, MessageHeader};
use {Io, Result};
pub struct FollowerInit<IO: Io> {
future: IO::SaveBallot,
pending_vote: Option<MessageHeader>,
}
impl<IO: Io> FollowerInit<IO> {
pub fn new(common: &mut Common<IO>, pending_vote: Option<MessageHeader>) -> Self {
let future = common.save_ballot();
FollowerInit {
future,
pending_vote,
}
}
pub fn handle_message(
&mut self,
common: &mut Common<IO>,
message: Message,
) -> Result<NextState<IO>> {
match message {
Message::RequestVoteCall(m) => {
self.pending_vote = Some(m.header);
}
Message::AppendEntriesCall(m) => {
common.rpc_callee(&m.header).reply_busy();
}
_ => {}
}
Ok(None)
}
pub fn run_once(&mut self, common: &mut Common<IO>) -> Result<NextState<IO>> {
let item = track!(self.future.poll())?;
if item.is_ready() {
if let Some(header) = self.pending_vote.take() {
common.rpc_callee(&header).reply_request_vote(true);
}
let next = if common.is_focusing_on_installing_snapshot() {
RoleState::Follower(Follower::Snapshot(FollowerSnapshot::new()))
} else {
RoleState::Follower(Follower::Idle(FollowerIdle::new()))
};
Ok(Some(next))
} else {
Ok(None)
}
}
}