lib.rs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. use std::{collections::HashMap, io, net::SocketAddr, time::Duration};
  2. use async_channel::{Receiver, Sender};
  3. use async_std::{
  4. io::{ReadExt, WriteExt},
  5. net::{TcpListener, TcpStream},
  6. stream::StreamExt,
  7. sync::Mutex,
  8. task,
  9. };
  10. use borsh::{BorshDeserialize, BorshSerialize};
  11. use futures::{select, FutureExt};
  12. use lazy_static::lazy_static;
  13. use log::{debug, error};
  14. use rand::Rng;
  15. mod method;
  16. use crate::method::{HeartbeatArgs, HeartbeatReply, RaftMethod, VoteArgs, VoteReply};
  17. #[derive(BorshSerialize, BorshDeserialize, Clone, Debug)]
  18. pub struct LogEntry {
  19. log_term: u64,
  20. log_index: u64,
  21. log_data: Vec<u8>,
  22. }
  23. pub struct LogStore(pub Vec<LogEntry>);
  24. impl LogStore {
  25. fn get_last_index(&self) -> u64 {
  26. let rlen = self.0.len();
  27. if rlen == 0 {
  28. return 0
  29. }
  30. self.0[rlen - 1].log_index
  31. }
  32. }
  33. lazy_static! {
  34. pub static ref LOG_STORE: Mutex<LogStore> = Mutex::new(LogStore(vec![]));
  35. // This is used for heartbeats
  36. pub static ref HEARTBEAT_CHAN: (Sender<bool>, Receiver<bool>) = async_channel::unbounded();
  37. // This is used to let our node know when it has become a leader
  38. pub static ref TOLEADER_CHAN: (Sender<bool>, Receiver<bool>) = async_channel::unbounded();
  39. pub static ref STATE: Mutex<State> = Mutex::new(State::new());
  40. }
  41. #[derive(Default)]
  42. pub struct State {
  43. pub current_term: u64,
  44. pub voted_for: u64,
  45. pub vote_count: u64,
  46. pub commit_index: u64,
  47. pub _last_applied: u64,
  48. pub next_index: Vec<u64>,
  49. pub match_index: Vec<u64>,
  50. }
  51. impl State {
  52. pub fn new() -> Self {
  53. Self {
  54. current_term: 0,
  55. voted_for: 0,
  56. vote_count: 0,
  57. commit_index: 0,
  58. _last_applied: 0,
  59. next_index: vec![],
  60. match_index: vec![],
  61. }
  62. }
  63. }
  64. pub enum Role {
  65. Follower,
  66. Candidate,
  67. Leader,
  68. }
  69. pub struct Raft {
  70. pub peers: HashMap<u64, SocketAddr>,
  71. node_id: u64,
  72. role: Role,
  73. }
  74. impl Raft {
  75. pub fn new(node_id: u64) -> Self {
  76. Self { peers: Default::default(), node_id, role: Role::Follower }
  77. }
  78. pub async fn start(&mut self) {
  79. debug!("Raft::start()");
  80. self.role = Role::Follower;
  81. let mut state = STATE.lock().await;
  82. state.current_term = 0;
  83. state.voted_for = 0;
  84. drop(state);
  85. let mut rng = rand::thread_rng();
  86. loop {
  87. let delay = Duration::from_millis(rng.gen_range(0..200) + 300);
  88. match self.role {
  89. Role::Follower => {
  90. select! {
  91. _ = HEARTBEAT_CHAN.1.recv().fuse() => {
  92. debug!("[FOLLOWER] Raft::start(): follower_{} got heartbeat", self.node_id);
  93. }
  94. _ = task::sleep(delay).fuse() => {
  95. debug!("[FOLLOWER] Raft::start(): follower_{} timeout", self.node_id);
  96. self.role = Role::Candidate;
  97. }
  98. }
  99. }
  100. Role::Candidate => {
  101. debug!("[CANDIDATE] Raft::start(): peer_{} is now a candidate", self.node_id);
  102. let mut state = STATE.lock().await;
  103. state.current_term += 1;
  104. state.voted_for = self.node_id;
  105. state.vote_count = 1;
  106. drop(state);
  107. // TODO: In background
  108. debug!("[CANDIDATE] Raft::start(): broadcasting request_vote");
  109. self.broadcast_request_vote().await;
  110. select! {
  111. _ = task::sleep(delay).fuse() => {
  112. debug!("[CANDIDATE] Raft::start(): Timeout as candidate, becoming a follower");
  113. self.role = Role::Follower;
  114. }
  115. _ = TOLEADER_CHAN.1.recv().fuse() => {
  116. debug!("[CANDIDATE] Raft::start(): We are now the leader");
  117. self.role = Role::Leader;
  118. let mut state = STATE.lock().await;
  119. state.next_index = vec![1_u64; self.peers.len()];
  120. state.match_index = vec![0_u64; self.peers.len()];
  121. drop(state);
  122. // TODO: In background
  123. let t = task::spawn(async {
  124. let mut i = 0;
  125. loop {
  126. debug!("[CANDIDATE] Raft::start(): Appending data in bg loop");
  127. i += 1;
  128. let state = STATE.lock().await;
  129. let logentry = LogEntry {
  130. log_term: state.current_term,
  131. log_index: i,
  132. log_data: format!("user send: {}", i).as_bytes().to_vec(),
  133. };
  134. drop(state);
  135. debug!("[CANDIDATE] Raft::start(): Acquiring logstore lock in bg loop");
  136. let mut logstore = LOG_STORE.lock().await;
  137. logstore.0.push(logentry);
  138. drop(logstore);
  139. debug!("[CANDIDATE] Raft::start(): Dropped logstore lock in bg loop");
  140. task::sleep(Duration::from_secs(3)).await;
  141. }
  142. });
  143. }
  144. }
  145. }
  146. Role::Leader => {
  147. debug!("[LEADER] Raft::start(): Broadcasting heartbeat as leader");
  148. self.broadcast_heartbeat().await;
  149. task::sleep(Duration::from_millis(100)).await;
  150. }
  151. }
  152. }
  153. }
  154. async fn broadcast_request_vote(&mut self) {
  155. debug!("Raft::broadcast_request_vote()");
  156. let state = STATE.lock().await;
  157. let args = VoteArgs { term: state.current_term, candidate_id: self.node_id };
  158. drop(state);
  159. // TODO: Do this concurrently
  160. for i in self.peers.clone() {
  161. debug!("Raft::broadcast_request_vote(): Sending req to peer {}", i.1);
  162. match self.send_request_vote(i.0, args.clone()).await {
  163. Ok(v) => debug!("Raft::broadcast_request_vote(): Got reply: {:?}", v),
  164. Err(e) => {
  165. error!("Raft::broadcast_request_vote(): Failed vote to peer {}, ({})", i.1, e);
  166. continue
  167. }
  168. };
  169. }
  170. }
  171. async fn send_request_vote(
  172. &mut self,
  173. node_id: u64,
  174. args: VoteArgs,
  175. ) -> Result<VoteReply, io::Error> {
  176. debug!("Raft::send_request_vote()");
  177. let addr = self.peers[&node_id];
  178. let method = RaftMethod::Vote(args);
  179. let payload = method.try_to_vec().unwrap();
  180. debug!("Raft::send_request_vote(): Connecting to peer_{}", node_id);
  181. let mut stream = TcpStream::connect(addr).await?;
  182. debug!("Raft::send_request_vote(): Writing to stream");
  183. stream.write_all(&payload).await?;
  184. debug!("Raft::send_request_vote(): Wrote to stream");
  185. debug!("Raft::send_request_vote(): Reading from stream");
  186. let mut buf = vec![0_u8; 4096];
  187. stream.read(&mut buf).await?;
  188. debug!("Raft::send_request_vote(): Read from stream");
  189. let reply = try_from_slice_unchecked::<VoteReply>(&buf)?;
  190. let mut state = STATE.lock().await;
  191. if reply.term > state.current_term {
  192. debug!("Raft::send_request_vote(): reply.term > state.current_term");
  193. state.current_term = reply.term;
  194. state.voted_for = 0;
  195. drop(state);
  196. self.role = Role::Follower;
  197. return Ok(reply)
  198. }
  199. drop(state);
  200. if reply.vote_granted {
  201. debug!("Raft::send_request_vote(): reply.vote_granted == true");
  202. let mut state = STATE.lock().await;
  203. state.vote_count += 1;
  204. drop(state);
  205. }
  206. let state = STATE.lock().await;
  207. if state.vote_count >= (self.peers.len() / 2 + 1).try_into().unwrap() {
  208. debug!("Raft::send_request_vote(): Elected for leader");
  209. TOLEADER_CHAN.0.send(true).await.unwrap();
  210. }
  211. drop(state);
  212. Ok(reply)
  213. }
  214. async fn broadcast_heartbeat(&mut self) {
  215. debug!("[LEADER] Raft::broadcast_heartbeat()");
  216. for i in self.peers.clone() {
  217. let state = STATE.lock().await;
  218. let mut args = HeartbeatArgs {
  219. term: state.current_term,
  220. leader_id: self.node_id,
  221. prev_log_index: 0,
  222. prev_log_term: 0,
  223. entries: vec![],
  224. leader_commit: state.commit_index,
  225. };
  226. let prev_log_index = state.next_index[i.0 as usize] - 1;
  227. drop(state);
  228. debug!("[LEADER] Raft::broadcast_heartbeat(): Acquiring lock on LOG_STORE");
  229. let logstore = LOG_STORE.lock().await;
  230. if logstore.get_last_index() > prev_log_index {
  231. args.prev_log_index = prev_log_index;
  232. args.prev_log_term = logstore.0[prev_log_index as usize].log_term;
  233. args.entries = logstore.0[prev_log_index as usize..].to_vec();
  234. drop(logstore);
  235. debug!("[LEADER] Raft::broadcast_heartbeat(): Dropped lock on LOG_STORE");
  236. debug!("[LEADER] Raft::broadcast_heartbeat(): Send entries: {:?}", args.entries);
  237. }
  238. // TODO: Run in background
  239. match self.send_heartbeat(i.0, args).await {
  240. Ok(v) => debug!("[LEADER] Raft::broadcast_heartbeat(): Got reply: {:?}", v),
  241. Err(e) => {
  242. error!(
  243. "[LEADER] Raft::broadcast_heartbeat(): Failed heartbeat to peer_{} ({})",
  244. i.0, e
  245. );
  246. continue
  247. }
  248. };
  249. }
  250. }
  251. async fn send_heartbeat(
  252. &mut self,
  253. node_id: u64,
  254. args: HeartbeatArgs,
  255. ) -> Result<HeartbeatReply, io::Error> {
  256. debug!("Raft::send_heartbeat({}, {:?}", node_id, args);
  257. let addr = self.peers[&node_id];
  258. let method = RaftMethod::Heartbeat(args);
  259. let payload = method.try_to_vec()?;
  260. debug!("Raft::send_heartbeat(): Connecting to peer_{}", node_id);
  261. let mut stream = TcpStream::connect(addr).await?;
  262. debug!("Raft::send_heartbeat(): Writing to stream");
  263. stream.write_all(&payload).await?;
  264. debug!("Raft::send_heartbeat(): Wrote to stream");
  265. debug!("Raft::send_heartbeat(): Reading from stream");
  266. let mut buf = vec![0_u8; 4096];
  267. stream.read(&mut buf).await?;
  268. debug!("Raft::send_heartbeat(): Read from stream");
  269. let reply = try_from_slice_unchecked::<HeartbeatReply>(&buf)?;
  270. let mut state = STATE.lock().await;
  271. if reply.success {
  272. debug!("Raft::send_heartbeat(): Got success reply");
  273. if reply.next_index > 0 {
  274. state.next_index[node_id as usize] = reply.next_index;
  275. state.match_index[node_id as usize] = reply.next_index - 1;
  276. }
  277. } else if reply.term > state.current_term {
  278. debug!("Raft::send_heartbeat(): reply.term > state.current_term");
  279. state.current_term = reply.term;
  280. state.voted_for = 0;
  281. self.role = Role::Follower;
  282. }
  283. drop(state);
  284. Ok(reply)
  285. }
  286. }
  287. pub struct RaftRpc(pub SocketAddr);
  288. impl RaftRpc {
  289. pub async fn start(&self) {
  290. debug!("RaftRpc::start()");
  291. debug!("RaftRpc::start(): Binding to {}", self.0);
  292. let listener = TcpListener::bind(self.0).await.unwrap();
  293. let mut incoming = listener.incoming();
  294. while let Some(stream) = incoming.next().await {
  295. debug!("RaftRpc::start(): Got RPC request");
  296. let stream = stream.unwrap();
  297. let (reader, writer) = &mut (&stream, &stream);
  298. debug!("RaftRpc::start(): Reading from reader...");
  299. let mut buf = vec![0_u8; 4096];
  300. reader.read(&mut buf).await.unwrap();
  301. debug!("RaftRpc::start(): Read from reader");
  302. match try_from_slice_unchecked::<RaftMethod>(&buf).unwrap() {
  303. RaftMethod::Vote(args) => {
  304. debug!("RaftRpc::start(): Got RaftMethod::Vote");
  305. let reply = self.request_vote(args).await;
  306. let payload = reply.try_to_vec().unwrap();
  307. debug!("RaftRpc::start(): Vote: Writing to writer...");
  308. writer.write_all(&payload).await.unwrap();
  309. debug!("RaftRpc::start(): Vote: Wrote to writer");
  310. }
  311. RaftMethod::Heartbeat(args) => {
  312. debug!("RaftRpc::start(): Got RaftMethod::Heartbeat");
  313. let reply = self.heartbeat(args).await;
  314. let payload = reply.try_to_vec().unwrap();
  315. debug!("RaftRpc::start(): Heartbeat: Writing to writer...");
  316. writer.write_all(&payload).await.unwrap();
  317. debug!("RaftRpc::start(): Heartbeat: Wrote to writer");
  318. }
  319. }
  320. }
  321. }
  322. async fn request_vote(&self, args: VoteArgs) -> VoteReply {
  323. debug!("RaftRpc::request_vote()");
  324. let mut reply = VoteReply { term: 0, vote_granted: false };
  325. debug!("RaftRpc::request_vote(): Acquiring state lock");
  326. let mut state = STATE.lock().await;
  327. debug!("RaftRpc::request_vote(): Got lock");
  328. if args.term < state.current_term {
  329. reply.term = state.current_term;
  330. drop(state);
  331. reply.vote_granted = false;
  332. return reply
  333. }
  334. if state.voted_for == 0 {
  335. state.current_term = args.term;
  336. state.voted_for = args.candidate_id;
  337. drop(state);
  338. reply.term = args.term;
  339. reply.vote_granted = true;
  340. return reply
  341. }
  342. drop(state);
  343. reply
  344. }
  345. async fn heartbeat(&self, args: HeartbeatArgs) -> HeartbeatReply {
  346. debug!("RaftRpc::heartbeat()");
  347. let mut reply = HeartbeatReply { success: false, term: 0, next_index: 0 };
  348. debug!("RaftRpc::heartbeat(): Acquiring state lock");
  349. let state = STATE.lock().await;
  350. debug!("RaftRpc::heartbeat(): Got state lock");
  351. let current_term = state.current_term;
  352. drop(state);
  353. debug!("RaftRpc::heartbeat(): Dropped state lock");
  354. if args.term < current_term {
  355. reply.success = false;
  356. reply.term = current_term;
  357. return reply
  358. }
  359. debug!("RaftRpc::heartbeat(): Sending to channel");
  360. HEARTBEAT_CHAN.0.send(true).await.unwrap();
  361. debug!("RaftRpc::heartbeat(): Sent to channel");
  362. if args.entries.is_empty() {
  363. reply.success = true;
  364. reply.term = current_term;
  365. return reply
  366. }
  367. debug!("RaftRpc::heartbeat(): Acquiring logstore lock");
  368. let mut logstore = LOG_STORE.lock().await;
  369. debug!("RaftRpc::heartbeat(): Got logstore lock");
  370. if args.prev_log_index > logstore.get_last_index() {
  371. reply.success = false;
  372. reply.term = current_term;
  373. reply.next_index = logstore.get_last_index() + 1;
  374. drop(logstore);
  375. return reply
  376. }
  377. logstore.0.extend_from_slice(&args.entries);
  378. reply.next_index = logstore.get_last_index() + 1;
  379. drop(logstore);
  380. debug!("RaftRpc::heartbeat(): Dropped logstore lock");
  381. reply.success = true;
  382. reply.term = current_term;
  383. reply
  384. }
  385. }
  386. fn try_from_slice_unchecked<T: BorshDeserialize>(data: &[u8]) -> Result<T, io::Error> {
  387. let mut data_mut = data;
  388. let result = T::deserialize(&mut data_mut)?;
  389. Ok(result)
  390. }